]> git.ipfire.org Git - thirdparty/binutils-gdb.git/commitdiff
This commit was manufactured by cvs2svn to create branch
authornobody <>
Fri, 20 Sep 2002 15:07:16 +0000 (15:07 +0000)
committernobody <>
Fri, 20 Sep 2002 15:07:16 +0000 (15:07 +0000)
'carlton_dictionary-branch'.

Cherrypick from master 2002-09-20 15:07:15 UTC Fernando Nasser <fnasser@redhat.com> '        From 2002-07-02  George Helffrich <george@gly.bris.ac.uk>':
    gdb/ChangeLog
    gdb/Makefile.in
    gdb/ada-lang.c
    gdb/c-lang.c
    gdb/dbxread.c
    gdb/mdebugread.c
    gdb/symfile.c
    gdb/symtab.c
    gdb/symtab.h
Cherrypick from gdb_5_3-branch 2002-09-03 22:29:15 UTC nobody 'This commit was manufactured by cvs2svn to create branch 'gdb_5_3-branch'.':
    gdb/coffread.c
    gdb/dwarf2read.c
    gdb/dwarfread.c
    gdb/hpread.c
    gdb/symfile.h
    gdb/xcoffread.c

15 files changed:
gdb/ChangeLog [new file with mode: 0644]
gdb/Makefile.in [new file with mode: 0644]
gdb/ada-lang.c [new file with mode: 0644]
gdb/c-lang.c [new file with mode: 0644]
gdb/coffread.c [new file with mode: 0644]
gdb/dbxread.c [new file with mode: 0644]
gdb/dwarf2read.c [new file with mode: 0644]
gdb/dwarfread.c [new file with mode: 0644]
gdb/hpread.c [new file with mode: 0644]
gdb/mdebugread.c [new file with mode: 0644]
gdb/symfile.c [new file with mode: 0644]
gdb/symfile.h [new file with mode: 0644]
gdb/symtab.c [new file with mode: 0644]
gdb/symtab.h [new file with mode: 0644]
gdb/xcoffread.c [new file with mode: 0644]

diff --git a/gdb/ChangeLog b/gdb/ChangeLog
new file mode 100644 (file)
index 0000000..ec776f7
--- /dev/null
@@ -0,0 +1,11415 @@
+2002-09-20  Fernando Nasser  <fnasser@redhat.com>
+
+       From 2002-07-02  George Helffrich <george@gly.bris.ac.uk>
+       * cli/cli-cmds.c (list_command): New function.  Implements the new
+       cli edit command.
+       (_init_cli_cmds): Add new command definition.
+       * gdb.1: Document edit command.
+       * doc/gdb.texinfo: Document edit command.
+
+2002-09-20  Fernando Nasser  <fnasser@redhat.com>
+
+       * source.c: Make global variables current_source_symtab and
+       current_source_line static.
+       (list_command): Moved to cli/cli-cmds.c.
+       (ambiguous_line_spec): Moved to cli/cli-cmds.c.
+       (get_first_line_listed): New accessor function.
+       (get_lines_to_list): New accessor function.
+       (get_current_source_symtab_and_line): New function. Retrieves the
+       position in the source code that we consider current.
+       (get_current_or_default_source_symtab_and_line): New function.
+       Like the above but attempts to determine a default position if one
+       is not currently defined.
+       (set_current_source_symtab_and_line): New function. Sets the source
+       code position considered current and returns the previously set one.
+       (clear_current_source_symtab_and_line): Reset stored information about
+       a current source line.
+       (_initialize_source): Remove registration for the "list" command and
+       its alias.
+       * source.h: Add declarations for the new functions above.
+       * symtab.h: Remove declarations for the global variables mentioned
+       above.
+       * breakpoint.c (parse_breakpoint_sals): Use accessor functions to
+       obtain current source line.
+       * linespec.c (decode_line_1): Ditto.
+       * macroscope.c (default_macro_scope): Ditto.
+       * scm-lang.c (scm_unpac): Ditto.
+       * stack.c (print_frame_info_base): Ditto.
+       * symfile.c (clear_symtab_users): Ditto.
+       * symtab.c (decode_line_spec): Ditto.
+       * cli/cli-cmds.c (list_command): Moved here from source.c.
+       (ambiguous_line_spec): Moved here from source.c.
+       (_init_cli_cmds): Add definition for "list" and its alias.
+       * Makefile.in: Update dependencies.
+
+2002-09-20  Corinna Vinschen  <vinschen@redhat.com>
+
+       * h8300-tdep.c (h8300_examine_prologue): Match saved regs location
+       with what gcc thinks is correct.
+
+2002-09-20  Corinna Vinschen  <vinschen@redhat.com>
+
+       * h8300-tdep.c (h8300_examine_prologue): Fix loop for saved regs in
+       multiple register push instruction.
+
+2002-09-19  Jim Blandy  <jimb@redhat.com>
+
+       Add support for distinct host and target character sets.
+       * charset.c, charset.h: New files.
+       * c-exp.y: #include "charset.h".
+       (yylex): Convert character and string literals to the target
+       character set, before returning them as the semantic value of the
+       token.
+       * c-lang.c: #include "charset.h".
+       (c_emit_char): Use charset-specific methods to recognize
+       characters with backslash escape forms, to decide which characters
+       to print literally and which to print using numeric escape
+       sequences, and to convert target characters to host characters
+       before printing.
+       * utils.c: #include "charset.h".
+       (no_control_char_error): New function.
+       (parse_escape): Use charset-specific methods to recognize
+       backslash escapes, parse `control character' notation, and convert
+       characters from the host character set to the target character set.
+       * configure.in: Set the default host character set.
+       Check where to find iconv, and what its argument types might be.
+       * acinclude.m4 (AM_ICONV): New macro, borrowed from GCC.
+       * Makefile.in (SFILES): List charset.c.
+       (COMMON_OBS): List charset.o.   
+       (charset.o): New rule.
+       (charset_h): New header dependency variable.
+       (c-lang.o, utils.o, c-exp.tab.o): Note dependency on $(charset_h).
+       (LIBICONV): New variable, set by configure.
+       (CLIBS): Include $(LIBICONV) here.
+       * aclocal.m4, config.in, configure: Regenerated.
+
+2002-09-19  Joel Brobecker  <brobecker@gnat.com>
+
+       * ada-exp.y: Add missing semicolons to end rules. Fixes a
+       bison 1.35 warning.
+
+2002-09-19  Richard Earnshaw  <rearnsha@arm.com>
+
+       * gdb_mbuild.sh: New file.
+
+2002-09-19  Andrew Cagney  <ac131313@redhat.com>
+
+       * objc-exp.y, objc-lang.h, objc-lang.c: Fix copyright notice.
+
+2002-09-18  Andrew Cagney  <ac131313@redhat.com>
+
+       * breakpoint.c, c-exp.y, defs.h, elfread.c, expression.h,
+       jv-exp.y, language.c, language.h, p-exp.y, parse.c, parser-defs.h,
+       printcmd.c, source.c, stabsread.c, symfile.c, symtab.h, utils.c,
+       valops.c, value.h: Revert previous change.
+       
+2002-09-18  Michael Snyder  <msnyder@redhat.com>
+
+       Preliminary support for Objective-C:
+       * defs.h (language_objc): New enum value.
+       (puts_filtered_tabular): Declaration only, exported from utils.c.
+       (skip_quoted): Delete, declared in completer.h.
+       * c-exp.y: Include completer.h.
+       * p-exp.y: Ditto.
+       * jv-exp.y: Ditto.
+       * expression.h (OP_MSGCALL, OP_SELECTOR, OP_SELF, OP_NSSTRING): 
+       New operator enum values.
+       * language.h (CAST_IS_CONVERSION): Test for language_objc.
+       * language.c (binop_result_type): Handle language_objc case.
+       (integral_type, character_type, string_type, boolean_type,
+       structured_type, binop_type_check): Ditto.
+       * symtab.h (SYMBOL_OBJC_DEMANGLED_NAME): Define.
+       (struct objc_specific): Add to general_symbol_info.
+       (SYMBOL_INIT_LANGUAGE_SPECIFIC): Add objc initialization.
+       (SYMBOL_DEMANGLED_NAME): Handle objc case.
+       * parser-defs.h (struct objc_class_str): New struct type.
+       (start_msglist, end_msglist, add_msglist): Declaration only,
+       exported from objc-lang.c.
+       * value.h (value_of_local, value_nsstring, 
+       call_function_by_hand_expecting_type): Exported from valops.c.
+       * valops.c (find_function_addr): Export.
+       (call_function_by_hand_expecting_type): New function.
+       (value_of_local): New function.
+       * symfile.c (init_filename_language_table): Add ".m" extension
+       for Objective-C.
+       * utils.c (puts_filtered_tabular): New function.
+       (fprintf_symbol_filtered): Add objc demangling support (disabled).
+       (set/show demangle): Extend help-string to refer to ObjC.
+       * elfread.c (elf_symtab_read): Skip Objective-C special symbols.
+       * stabsread.c (symbol_reference_defined): Objective-C symbols
+       may contain colons: make allowances when scanning stabs strings
+       for colons.
+       (objc_find_colon): New function.
+       * printcmd.c (address_info): If language == objc then print
+       "self" instead of "this".
+       * parse.c (length_of_subexp): Handle new operators OP_MSGCALL,
+       OP_NSSTRING, and OP_SELF.
+       (prefixify_subexp): Ditto.
+       * source.c (print_source_lines): Mention objc in comment.
+       * breakpoint.c (parse_breakpoint_sals): Recognize Objective-C
+       method names.
+
+2002-09-18  Andrew Cagney  <ac131313@redhat.com>
+
+       * complaints.h: Update copyright.
+       (struct complaints): Declare.
+       (struct complaint): Make `message' constant.
+       (internal_complaint): Declare.
+       (complaint): Declare.
+       (complaint_root): Delete declaration.
+       (symfile_complaints): Delete declaration.
+       (struct complaints): Add opaque declaration.
+       (clear_complaints): Add a complaints parameter.
+       * complaints.c: Update copyright.
+       (enum complaint_series): Define.
+       (complaint_root): Delete.
+       (struct complaints): Define.
+       (complaint_sentinel, symfile_complaint_book): New variables.
+       (symfile_explanations, symfile_complaints): New variables.
+       New variables.
+       (get_complaints): New function.
+       (vcomplaint): New function.
+       (complaint): New function.
+       (internal_complaint): New function.
+       (complain): Call vcomplain with symfile_complaint.
+       (clear_complaints): Rewrite.
+       (_initialize_complaints): Use add_setshow_command.
+       * Makefile.in (complaints.o): Update dependencies.
+       * symfile.c (syms_from_objfile): Add symfile_complaints parameter
+       to call to clear_complaints.
+       (new_symfile_objfile, reread_symbols): Ditto.
+       (oldsyms_complaint): Delete.
+       (empty_symtab_complaint, unknown_option_complaint): Delete.
+       (free_named_symtabs): Use complaint instead of complain.
+
+2002-09-18  Michael Snyder  <msnyder@redhat.com>
+
+       Contributed by Apple Computer, Inc.  Merged with current sources
+       by Adam Fedor <fedor@doc.com> [cagney].
+       
+       * objc-lang.c: First clean-up round: comments, indentation.
+       * objc-lang.h: Ditto.
+       * objc-lang.y: Ditto.
+
+2002-09-18  Andrew Cagney  <ac131313@redhat.com>
+
+       * maint.c (maintenance_internal_error): Print the parameter as the
+       error message.
+       (maintenance_internal_warning): New function.
+       (_initialize_maint_cmds): Add command `maint internal-warning'.
+
+       * defs.h (internal_warning, internal_vwarning): Declare.
+       * utils.c (struct internal_problem): Define.
+       (internal_vproblem): New function.
+       (internal_warning): New function.
+       (internal_vwarning): New function.
+       (internal_warning_problem, internal_error_problem): New variables.
+       (internal_verror): Just call internal_vproblem.
+
+2002-09-18  Michael Snyder  <msnyder@redhat.com>
+
+       * objc-lang.c: New file, support for Objective-C.
+       Preliminary check-in, not yet integrated into gdb.
+       * objc-lang.h: New file.
+       * objc-exp.y:  New file.
+
+2002-09-18  Andrew Cagney  <ac131313@redhat.com>
+
+       * infrun.c (signal_stop_update): Convert definition to ISO C.
+       (signal_print_update): Ditto.
+       (signal_pass_update): Ditto.
+       * inflow.c (terminal_save_ours): Ditto.
+
+       * h8300-tdep.c (h8300_gdbarch_init): Use C instead of C++
+       comments.
+       
+       * config/djgpp/fnchange.lst: Handle name clashes between
+       bfd/coff-tic30.c, bfd/coff-tic4x.c, bfd/coff-tic54x.c and
+       bfd/coff-tic80.c.
+
+       * i386-linux-tdep.h: Fix tipo.
+
+2002-09-18  Adam Fedor  <fedor@gnu.org>
+
+       * MAINTAINERS: Add myself to the Write After Approval list.
+
+2002-09-18  Jim Blandy  <jimb@redhat.com>
+
+       * dbxread.c, mdebugread.c: Revert my change of 2001-10-23.  Moving
+       texthigh and textlow to reader-specific structs caused
+       objfile_relocate to miss them.  This is fixable, but the work that
+       the change was supposed to prepare GDB for never got done anyway.
+
+2002-09-18  David Carlton  <carlton@math.stanford.edu>
+
+       * MAINTAINERS: Alphabetize Write After Approval list.
+
+2002-09-18  Daniel Jacobowitz  <drow@mvista.com>
+
+       Fix PR gdb/709
+       * values.c (value_static_field): Call read_var_value.
+
+2002-09-18  Andrew Cagney  <ac131313@redhat.com>
+
+       * valops.c (hand_function_call): Align the initial stack pointer
+       and STRUCT_ADDR using frame_align.  When STRUCT_RETURN and
+       FRAME_ALIGN_P, use STRUCT_ADDR to obtain the called function's
+       return value.
+       * mips-tdep.c (mips_frame_align): New function.
+       (mips_gdbarch_init): Set frame_align.
+       * gdbarch.sh (FRAME_ALIGN): New method.
+       * gdbarch.h, gdbarch.c: Re-generate.
+
+2002-09-18  Michal Ludvig  <mludvig@suse.cz>
+
+       * x86-64-linux-nat.c (x86_64_regmap): Added CS and SS
+       registers.
+
+2002-09-17  Andrew Cagney  <ac131313@redhat.com>
+
+       * NEWS: Mention that MIPS $fp behavior changed.
+       * mipsnbsd-tdep.c (mipsnbsd_cannot_fetch_register): Delete
+       reference to FP_REGNUM.
+       (mipsnbsd_cannot_store_register): Ditto.
+       * mips-linux-nat.c: Update copyright.
+       (mips_linux_cannot_fetch_register): Delete reference to FP_REGNUM.
+       (mips_linux_cannot_store_register): Ditto.
+       * mips-linux-tdep.c (supply_gregset): Ditto.  Update copyright.
+       * config/mips/tm-mips.h: Update copyright.
+       (FP_REGNUM): Delete macro.
+       (MIPS_REGISTER_NAMES): Replace "fp" with "".
+       * config/mips/tm-irix6.h (FP_REGNUM): Delete macro.
+       * mips-tdep.c (mips_gdbarch_init): Set read_fp to mips_read_sp.
+       (mips_r3041_reg_names, mips_r3051_reg_names)
+       (mips_r3081_reg_names): Replace "fp" with "".
+       Fix PR gdb/480.
+
+2002-09-17  Theodore A. Roth  <troth@verinet.com>
+
+       * gdb/avr-tdep.c(avr_scan_prologue): Fix bad call to 
+       generic_read_register_dummy() (PR gdb/703).
+       (avr_push_return_address): #if 0 out unused vars.
+       (avr_gdbarch_init): Enable use of avr_push_return_address().
+
+2002-09-17  Michael Snyder  <msnyder@redhat.com>
+
+       * m32r-stub.c (restore_and_return): Postpone restoring of PSW.
+       RTE will take care of it.
+
+2002-09-17  Andrew Cagney  <ac131313@redhat.com>
+
+       * arch-utils.c (legacy_virtual_frame_pointer): If FP_REGNUM is
+       invalid, return SP_REGNUM.
+
+2002-09-17  Michael Snyder  <msnyder@redhat.com>
+
+       * mips-tdep.c (mips_pop_frame): Read saved values of floating
+       point registers without sign extension.
+
+2002-09-17  Andrew Cagney  <cagney@redhat.com>
+
+       * blockframe.c (deprecated_read_register_dummy): Rename
+       generic_read_register_dummy.
+       * frame.c (frame_unwind_signed_register): New function.
+       (frame_unwind_unsigned_register): New function.
+       * frame.h (frame_unwind_signed_register): Declare.
+       (frame_unwind_unsigned_register): Declare.
+       (deprecated_read_register_dummy): Rename
+       generic_read_register_dummy.
+
+       * h8300-tdep.c (h8300_frame_chain): Update.
+       (h8300_frame_saved_pc): Update.
+       * xstormy16-tdep.c (xstormy16_frame_saved_pc): Update.
+       * rs6000-tdep.c (rs6000_frame_saved_pc): Update.
+       * s390-tdep.c (s390_frame_saved_pc_nofix): Update.
+       (s390_frame_chain): Update.
+       * v850-tdep.c (v850_find_callers_reg): Update.
+       (v850_frame_saved_pc): Update.
+       * m32r-tdep.c (m32r_init_extra_frame_info): Update.
+       (m32r_find_callers_reg): Update.
+       (m32r_frame_saved_pc): Update.
+       * sh-tdep.c (sh_find_callers_reg): Update.
+       (sh64_get_saved_pr): Update.
+       (sh_init_extra_frame_info): Update.
+       (sh_init_extra_frame_info): Update.
+       (sh64_init_extra_frame_info): Update.
+       (sh64_init_extra_frame_info): Update.
+       * mcore-tdep.c (mcore_find_callers_reg): Update.
+       (mcore_frame_saved_pc): Update.
+       (mcore_init_extra_frame_info): Update.
+       * i386-tdep.c (i386_frame_saved_pc): Update.
+       * ia64-tdep.c (ia64_frame_saved_pc): Update.
+       (ia64_init_extra_frame_info): Update.
+       (ia64_init_extra_frame_info): Update.
+       * d10v-tdep.c (d10v_frame_saved_pc): Update.
+       * cris-tdep.c (cris_init_extra_frame_info): Update.
+       * avr-tdep.c (avr_frame_chain): Update.
+       (avr_init_extra_frame_info): Update.
+       (avr_frame_saved_pc): Update.
+       * arm-tdep.c (arm_find_callers_reg): Update.
+       (arm_init_extra_frame_info): Update.
+       (arm_frame_saved_pc): Update.
+
+2002-09-17  Tom Tromey  <tromey@redhat.com>
+
+       * c-lang.c (c_emit_char): Don't treat \0 specially unless quoter
+       is "'".
+
+2002-09-17  Corinna Vinschen  <vinschen@redhat.com>
+
+       * MAINTAINERS: Remove "non multi-arched" text from h8300.
+       * h8300-tdep.c (h8300_next_prologue_insn) Renamed from
+       NEXT_PROLOGUE_INSN.
+       (h8300_examine_prologue): Call h8300_next_prologue_insn instead of
+       NEXT_PROLOGUE_INSN.
+
+2002-09-16  Joel Brobecker  <brobecker@gnat.com>
+
+       * osfsolib.c: Remove file, replaced by solib-osf.c.
+       * Makefile.in: Remove compilation rules for osfsolib.c.
+
+2002-09-16  David Carlton  <carlton@math.stanford.edu>
+
+       * cp-valprint.c (cp_print_class_method): Correct args to
+       check_stub_method_group.
+
+2002-09-16  Corinna Vinschen  <vinschen@redhat.com>
+
+       * h8300-tdep.c: Multiarch.  Drop `set machine' command in favor of
+       `set architecture'.  Unify naming convention of functions.
+       (h8300_skip_prologue): Improve prologue analysis.
+       (h8300_push_arguments): Rewritten to more closely match GCC's
+       bizarre argument-passing behavior, along with the comment describing
+       said behavior.
+       * remote-hms.c (hms_regnames): Don't use NUM_REGS in definition.
+       * config/h8300/tm-h8300.h: Multiarch.  Just keep stuff needed by
+       sim, remote-e7000.c, remote-hms.c and remote.c
+
+2002-09-15  Mark Kettenis  <kettenis@gnu.org>
+
+       * i386-tdep.c (gdb_print_insn_i386): Removed.
+       (i386_print_insn): New function.
+       (i386_gdbarch_init): Set print_insn to i386_print_insns.
+       (_initialize_i386_tdep): Don't initialize tm_print_insn and
+       tm_print_insn_info.
+
+2002-09-14  Mark Kettenis  <kettenis@gnu.org>
+
+       * gdbtypes.c (check_stub_method_group): Initialize found_stub to
+       zero.
+
+2002-09-14  Corinna Vinschen  <vinschen@redhat.com>
+
+       * arch-utils.c (legacy_pc_in_sigtramp): Move preprocessor expression
+       for IN_SIGTRAMP to here.  Use IN_SIGTRAMP only if it's defined. 
+       Guard usage of SIGTRAMP_START() by using SIGTRAMP_START_P.
+
+2002-09-13  Christopher Faylor  <cgf@redhat.com>
+
+       * win32-nat.c (child_create_inferior): Honor 'tty' command.
+
+2002-09-13  Daniel Jacobowitz  <drow@mvista.com>
+
+       * gdbtypes.c (check_stub_method): Make static.
+       (check_stub_method_group): New function.
+       * gdbtypes.h: Update prototypes.
+       * cp-support.c: New file.
+       * cp-support.h: New file.
+
+       * stabsread.c: Include "cp-abi.h" and "cp-support.h".
+       (update_method_name_from_physname): New function.
+       (read_member_functions): Correct method names for operators
+       and v3 constructors/destructors.  Separate v2 constructors and
+       destructors.
+       * Makefile.in (stabsread.o): Update dependencies.
+       (SFILES): Add cp-support.c.
+       (COMMON_OBS): Add cp-support.o.
+       (cp_support_h, cp-support.o): Add.
+
+       * cp-valprint.c (cp_print_class_method): Call
+       check_stub_method_group instead of check_stub_method.  Remove
+       extraneous QUITs.
+       * p-valprint.c (pascal_object_print_class_method): Likewise.
+       * valops.c (search_struct_method): Likewise.
+       (find_method_list, value_struct_elt_for_reference): Likewise.
+
+2002-09-13  Andrew Cagney  <cagney@redhat.com>
+
+       * gdbarch.sh (SIGTRAMP_END): Change to a predicate function.
+       * gdbarch.h, gdbarch.c: Regenerate.
+
+2002-09-13  Andrew Cagney  <ac131313@redhat.com>
+
+       * frame.c (find_saved_register): Delete function.
+       * frame.h (find_saved_register): Delete declaration.
+       Fix PR gdb/631.
+
+Fri Sep 13 14:59:55 2002  Andrew Cagney  <cagney@redhat.com>
+
+       * mips-tdep.c (read_next_frame_reg): Re-hack using
+       frame_register_unwind.
+
+Fri Sep 13 07:42:09 2002  Andrew Cagney  <cagney@redhat.com>
+
+       * mips-tdep.c (mips_get_saved_register): Re-hack using
+       frame_register_unwind.
+
+2002-09-12  Joel Brobecker  <brobecker@gnat.com>
+
+       * gdbarch.sh (NAME_OF_MALLOC): New variable in the architecture
+       vector. Will be useful for Interix.  
+       * gdbarch.h, gdbarch.c: Regenerate.
+
+       * valops.c (value_allocate_space_in_inferior): Replace hard-coded
+       name of the malloc function by NAME_OF_MALLOC.
+
+2002-09-12  Joel Brobecker  <brobecker@gnat.com>
+
+       * value.h (find_function_in_inferior): Add const keyword to
+       one of the parameters. Allows us to invoke this function with
+       a const char *.
+       * valops.c (find_function_in_inferior): Likewise.
+
+2002-09-12  Joel Brobecker  <brobecker@gnat.com>
+
+       * exec.c (xfer_memory): Fix compilation warning with old versions
+       of GCC.
+       * tracepoint.c (trace_find_tracepoint_command): Likewise.
+
+2002-09-12  David Carlton  <carlton@math.stanford.edu>
+
+       * symtab.h: Run through gdb_indent.h.
+       Add 2002 to Copyright year list.
+
+2002-09-12  Alan Modra  <amodra@bigpond.net.au>
+
+       * x86-64-tdep.c (_initialize_x86_64_tdep): Don't use hard-coded
+       mach constants.
+       * MAINTAINERS: Add myself to write after approval list.
+
+2002-09-11  J. Brobecker  <brobecker@gnat.com>
+
+       * osabi.c (gdb_osabi_name): Add entry for GDB_OSABI_INTERIX.
+
+2002-09-11  J. Brobecker  <brobecker@gnat.com>
+
+       * osabi.h (gdb_osabi): Add new GDB_OSABI_INTERIX enum value for
+       Interix.
+
+2002-06-05  Paul N. Hilfinger  <hilfingr@otisco.mckusick.com>
+
+       * procfs.c (do_detach): Clear current signal, not just fault.
+       Corrects problem with breakpoint trap signal leaking to detached
+       process on Tru64.
+
+2002-09-10  Michael Snyder  <msnyder@redhat.com>
+
+       * buildsym.c (finish_block): Protect against null pointer.
+
+2002-09-10  Andrew Cagney  <cagney@redhat.com>
+
+       * infcmd.c (default_print_registers_info): Send all output to
+       ``file'' instead of ``gdb_stdout''.
+
+2002-09-10  Michael Snyder  <msnyder@redhat.com>
+
+       * mips-tdep.c (mips_extract_struct_value_address): Make val a
+       LONGEST, and use signed register read (addresses are sign-
+       extended for mips).
+
+2002-09-10  Stephane Carrez  <stcarrez@nerim.fr>
+
+       * event-loop.c (gdb_do_one_event): Make public.
+       * event-loop.h (gdb_do_one_event): Declare.
+
+2002-09-10  Jeff Law  <law@redhat.com>
+
+       * infttrace.c (child_resume): Simplify and rework to avoid
+       TT_PROC_CONTINUE.
+
+2002-09-09  Fred Fish  <fnf@intrinsity.com>
+
+       * printcmd.c (print_scalar_formatted): "len" is the number of
+       target bytes, NOT the number of target bits.
+
+2002-09-09  Elena Zannoni  <ezannoni@redhat.com>
+
+       From: Emmanuel Thome'  <thome@lix.polytechnique.fr>
+       * top.c (init_main): Set rl_terminal_name.
+
+2002-09-08  Aidan Skinner <aidan@velvet.net>
+
+       * ada-lang.c (ada_array_bound, ada_type_match,
+       _initialize_ada_language): Fix K&R definitions.
+       * ada-tasks.c (get_current_task): Fix K&R definitions.
+       * ada-valprint.c (adjust_type_signedness): Fix K&R definitions.
+                       
+2002-09-07  Christopher Faylor  <cgf@redhat.com>
+
+       * MAINTAINERS: Remove CE from list of maintainership responsibilities.
+       Add XP.
+
+2002-09-06  Mark Kettenis  <kettenis@gnu.org>
+
+       * i386-tdep.c (i386_register_virtual_type,
+       i386_register_convertible, i386_register_convert_to_virtual,
+       i386_register_comvert_to_raw): Use FP_REGNUM_P and SSE_REGNUM_P
+       instead of IS_FP_REGNUM and IS_SSE_REGNUM.
+       (i386_gdbarch_init): Fix comment.  Add comments on calls that set
+       sp_regnum, fp_regnum, pc_regnum, ps_regnum and fp0_regnum.
+       Don't set push_arguments twice.
+
+       * i386bsd-tdep.c (i386bsd_init_abi): Set sigtramp_start and
+       sigtramp_end to i386bsd_sigtramp_start and i386bsd_sigtramp_end.
+       * i386nbsd-tdep.c (i386nbsd_init_abi): Set sigtramp_start and
+       sigtramp_end to NULL.
+       * config/i386/tm-fbsd.h (SIGTRAMP_START, SIGTRAMP_END): Remove
+       defines.
+       (i386bsd_sigtramp_start, i386_sigtramp_end): Remove prototypes.
+
+       * i386nbsd-tdep.c (i386nbsd_pc_in_sigtramp): Remove spurious
+       whitespace.
+
+       * gdbarch.sh (SIGTRAMP_START, SIGTRAMP_END): New methods.
+       * gdbarch.h, gdbarch.c: Re-generate.
+       * blockframe.c (find_pc_sect_partial_function): Convert to use
+       SIGTRAMP_START_P predicate.
+
+2002-09-05  Michael Snyder  <msnyder@redhat.com>
+
+       * arm-tdep.c (arm_init_extra_frame_info): Distinguish between
+       generic_dummy_frame method and old method.  Also distinguish
+       between ARM_FP_REGNUM and THUMB_FP_REGNUM.
+       (arm_extract_return_value): Use new regcache method.
+
+       * mips-tdep.c (mips_n32n64_push_arguments): Remove alignment
+       adjustment that doesn't conform to the ABI.
+       (mips_extract_struct_value_address): Retrieve V0_REGNUM from
+       saved regcache, not from current regcache.
+
+2002-09-05  Andrew Cagney  <ac131313@redhat.com>
+
+       * NEWS: Update for 5.3.  Add new section ``Changes since 5.3''.
+       * README: Update.
+
+2002-09-04  Jason Thorpe  <thorpej@wasabisystems.com>
+
+       * arm-tdep.c (arm_addr_bits_remove): Don't check for Thumb mode
+       if arm_apcs_32 is false.
+
+2002-09-04  Andrew Cagney  <ac131313@redhat.com>
+
+       GDB 5.3 branch created.
+
+2002-09-03  Theodore A. Roth  <troth@verinet.com>
+
+       * gdb/avr-tdep.c (avr_gdbarch_init): Use
+       generic_unwind_get_saved_register.
+
+2002-09-03  David Carlton  <carlton@math.stanford.edu>
+
+       * dwarf2read.c (dwarf2_add_member_fn): Add the 'type'
+       argument (PR gdb/653).  Update call to smash_to_method_type.
+       (read_structure_scope): Update call to dwarf2_add_member_fn.
+
+2002-09-03  Michal Ludvig  <mludvig@suse.cz>
+
+       * x86-64-linux-tdep.c: Include gdb_string.h
+       * x86-64-linux-nat.c: Ditto.
+
+2002-09-02  Jason Thorpe  <thorpej@wasabisystems.com>
+
+       * ada-exp.y (yyname, yyrule): Remap global variables that appear
+       when YYDEBUG is set to 1.  
+       * c-exp.y: Likewise.
+       * f-exp.y: Likewise.
+       * jv-exp.y: Likewise.
+       * m2-exp.y: Likewise.
+       * p-exp.y: Likewise.
+
+2002-09-02  Jason Thorpe  <thorpej@wasabisystems.com>
+
+       * Makefile.in (i386nbsd-tdep.o): Add $(solib_svr4_h) to
+       dependency list.
+       * i386nbsd-tdep.c (i386nbsdelf_init_abi): Set
+       solib_svr4_fetch_link_map_offsets to
+       nbsd_ilp32_solib_svr4_fetch_link_map_offsets.
+       * config/i386/nbsd.mt (TDEPFILES): Add solib.o and solib-svr4.o.
+       * config/i386/nbsdaout.mh (NATDEPFILES): Remove solib.o.
+       * config/i386/nbsdelf.mh (NATDEPFILES): Remove solib.o,
+       solib-svr4.o, and solib-legacy.o.
+       * config/i386/tm-nbsd.h: Include solib.h.
+
+2002-09-02  Jason Thorpe  <thorpej@wasabisystems.com>
+
+       * configure.tgt (i[3456]86-*-netbsdelf*): Merge with... 
+       (i[3456]86-*-netbsd*): ...this.  Set gdb_target to nbsd. 
+       (i[3456]86-*-openbsd*): Make this a separate entry.  Add a
+       comment noting that this needs its own target configuration.
+       * config/i386/nbsd.mt: New file.
+       * config/i386/nbsdaout.mt: Remove.
+       * config/i386/nbsdelf.mt: Ditto.
+       * config/i386/tm-nbsdaout.h: Ditto. 
+
+2002-09-02  Jason Thorpe  <thorpej@wasabisystems.com>
+
+       * i386nbsd-tdep.c (i386nbsd_sigtramp_offset): New function. 
+       (i386nbsd_pc_in_sigtramp): Rewrite to use i386nbsd_sigtramp_offset. 
+       (i386nbsd_init_abi): Don't initialize tdep->sigtramp_start or
+       tdep->sigtramp_end.
+       (i386nbsd_sigtramp_start, i386nbsd_sigtramp_end): Remove. 
+       * config/i386/tm-nbsd.h (SIGTRAMP_START, SIGTRAMP_END)
+       (i386bsd_sigtramp_start, i386bsd_sigtramp_end): Remove.
+
+2002-09-02  Jason Thorpe  <thorpej@wasabisystems.com>
+
+       * Makefile.in (i386nbsd-tdep.o): Add $(arch_utils_h),
+       $(i386_tdep_h), and $(nbsd_tdep_h) to dependency list.
+       * i386-tdep.h (i386bsd_init_abi): New prototype.
+       * i386bsd-tdep.c (i386bsd_init_abi): Remove "static" from
+       function declaration.
+       (_initialize_i386bsd_tdep): Don't register OS ABI handlers
+       for NetBSD-a.out or NetBSD-ELF.
+       (i386nbsd_sigtramp_start, i386nbsd_sigtramp_end)
+       (i386nbsd_sc_pc_offset, i386nbsd_sc_sp_offset)
+       (i386nbsd_init_abi, i386nbsdelf_init_abi): Move to...
+       * i386nbsd-tdep.c: ...here.  Include arch-utils.h, i386-tdep.h,
+       and nbsd-tdep.h.
+       (i386nbsd_pc_in_sigtramp): New function.
+       (i386nbsd_init_abi): Set gdbarch_pc_in_sigtramp to
+       i386nbsd_pc_in_sigtramp.
+       (_initialize_i386nbsd_tdep): Register i386nbsd_init_abi
+       and i386nbsdelf_init_abi OS ABI handlers.
+       * config/i386/nbsdaout.mt (TDEPFILES): Add nbsd-tdep.o.
+       * config/i386/nbsdelf.mt (TDEPFILES): Likewise.
+
+2002-09-02  Mark Kettenis  <kettenis@gnu.org>
+
+       * i386-linux-nat.c (dummy_sse_values): Only try to fill in the SSE
+       registers if the target really has them.
+
+2002-08-31  Jason Thorpe  <thorpej@wasabisystems.com>
+
+       * Makefile.in (mipsnbsd-tdep.o): Use $(nbsd_tdep_h) rather
+       than nbsd-tdep.h.
+
+2002-08-31  Jason Thorpe  <thorpej@wasabisystems.com>
+
+       * Makefile.in (alphanbsd-tdep.o): Add $(frame_h) to dependency
+       list.
+       * alphanbsd-tdep.c (alphanbsd_sigcontext_addr)
+       (alphanbsd_skip_sigtramp_frame): New functions. 
+       (alphanbsd_init_abi): Set tdep->skip_sigtramp_frame to
+       alphanbsd_skip_sigtramp_frame.  Set tdep->sigcontext_addr
+       to alphanbsd_sigcontext_addr. 
+
+2002-08-31  Jason Thorpe  <thorpej@wasabisystems.com>
+
+       * Makefile.in (mipsnbsd-tdep.o): Add nbsd-tdep.h to dependency
+       list.
+       (nbsd-tdep.o): Add $(gdb_string_h) to dependency list. 
+       * alphanbsd-tdep.c (alphanbsd_pc_in_sigtramp): Use
+       nbsd_pc_in_sigtramp. 
+       * mipsnbsd-tdep.c: Include nbsd-tdep.h.
+       (mipsnbsd_pc_in_sigtramp): Use nbsd_pc_in_sigtramp.
+       * nbsd-tdep.c: Include gdb_string.h.
+       (nbsd_pc_in_sigtramp): New function. 
+       * nbsd-tdep.h (nbsd_pc_in_sigtramp): New prototype. 
+       * ppcnbsd-tdep.c (ppcnbsd_pc_in_sigtramp): New function.
+       (ppcnbsd_init_abi): Set gdbarch_pc_in_sigtramp to
+       ppcnbsd_pc_in_sigtramp. 
+       * shnbsd-tdep.c (shnbsd_pc_in_sigtramp): New function.
+       (shnbsd_init_abi): Set gdbarch_pc_in_sigtramp to
+       shnbsd_pc_in_sigtramp. 
+       * sparcnbsd-tdep.c (sparcnbsd_init_abi_elf): Set
+       gdbarch_pc_in_sigtramp to nbsd_pc_in_sigtramp. 
+       * config/mips/nbsd.mt (TDEPFILES): Add nbsd-tdep.o.
+
+2002-08-30  Pierre Muller  <muller@ics.u-strasbg.fr>
+
+       * breakpoint.c (breakpoint_init_inferior): Reset the val field of
+       watchpoints to NULL.
+       (insert_breakpoints): set val field of watchpoints if NULL.
+
+
+2002-08-29  Jim Blandy  <jimb@redhat.com>
+
+       * symtab.c (lookup_symbol_aux): In the cases where we find a
+       minimal symbol of an appropriate name and use its address to
+       select a symtab to read and search, use `name' (as passed to us)
+       as the demangled name when searching the symtab's global and
+       static blocks, not the minsym's name.
+
+2002-08-29  Keith Seitz  <keiths@redhat.com>
+
+       * stack.c (print_frame_info_base): Always set current_source_symtab
+       and current_source_line.
+
+2002-08-29  Donn Terry  <donnte@microsoft.com>
+
+       * proc-api.c (rw_table): Fix typo in #ifdef PCSHOLD (missing S).
+
+2002-08-28  Keith Seitz  <keiths@redhat.com>
+
+       * stack.c (select_frame): Add FIXME concerning selected-frame
+       events.
+       (select_frame_command): Send selected-frame-level-changed
+       event notification, but only if the level actually changed.
+       (up_silently_base): Add selected-frame-level-changed event
+       notification.
+       (down_silently_base): Likewise.
+
+2002-08-28  Andrew Cagney  <ac131313@redhat.com>
+
+       * Makefile.in: Update dependencies for all gdb/*.c files.
+
+2002-08-27  Tom Tromey  <tromey@redhat.com>
+
+       * Makefile.in (osabi.o, i387-tdep.o, i386-linux-nat.o, lin-lwp.o,
+       ax-gdb.o, signals.o, jv-valprint.o, c-valprint.o, cp-abi.o):
+       Update dependencies.
+       * i387-tdep.c: Include gdb_string.h.
+       * osabi.c: Likewise.
+       * i386-linux-nat.c: Likewise.
+       * lin-lwp.c: Likewise.
+       * ax-gdb.c: Likewise.
+       * signals/signals.c: Likewise.
+       * jv-valprint.c: Likewise.
+       * p-lang.c: Likewise.
+       * c-valprint.c: Likewise.
+       * cp-abi.c: Likewise.
+
+2002-08-27  Elena Zannoni  <ezannoni@redhat.com>
+
+       * cli/cli-script.h (copy_command_lines): Export.
+       * breakpoint.c: Include cli/cli-script.h.
+       * Makefile.in (breakpoint.o): Update dependencies.
+
+2002-08-26  Michael Snyder  <msnyder@redhat.com>
+
+       * breakpoint.c (insert_breakpoints): Protect all references
+       to 'process_warning'.  Shorten long lines.
+
+2002-08-26  Joel Brobecker  <brobecker@gnat.com>
+
+       * cli/cli-script.c (copy_command_lines): New function.
+       * defs.h (copy_command_lines): Export.
+       * testsuite/gdb.base/commands.exp: New tests for commands
+       attached to a temporary breakpoint, and for commands that
+       delete the breakpoint they are attached to.
+       
+2002-08-26  Michael Snyder  <msnyder@redhat.com>
+
+       * breakpoint.c (bpstat_stop_status): Instead of copying the 
+       pointer to the breakpoint commands struct, make a new copy
+       of the struct and point to that.
+       (bpstat_clear): Free the commands struct.
+       (bpstat_clear_actions): Free the commands struct.
+       (bpstat_do_actions): Free the command actions.  Also execute
+       the local cleanups, instead of deleting them.
+       (delete_breakpoint): Leave the commands field of the bpstat
+       chain alone -- it will be freed later.
+
+2002-08-26  Kevin Buettner  <kevinb@redhat.com>
+
+       * rs6000-tdep.c (altivec_register_p): Restore function inadvertently
+       deleted in 2002-08-20 commit.  This function is still used by
+       ppc-linux-nat.c.
+
+2002-08-26  Keith Seitz  <keiths@redhat.com>
+
+       * gdb-events.sh: Add selected-frame-level-changed event.
+       * gdb-events.c: Regenerated.
+       * gdb-events.h: Regenerated.
+       
+2002-08-26  Stephane Carrez  <stcarrez@nerim.fr>
+
+       Fix PR gdb/393:
+       * inflow.c (terminal_save_ours): New function to save terminal
+       settings.
+       * inferior.h (terminal_save_ours): Declare.
+       * target.c (debug_to_terminal_save_ours): New function.
+       (cleanup_target): Defaults to_terminal_save_ours.
+       (update_current_target): Inherit to_terminal_save_ours.
+       (setup_target_debug): Set to_terminal_save_ours.
+       * target.h (target_terminal_save_ours): New to save terminal settings.
+       (target_ops): New member to_terminal_save_ours.
+       * gnu-nat.c (init_gnu_ops): Set to_terminal_save_ours.
+       * hpux-thread.c (init_hpux_thread_ops): Likewise.
+       * inftarg.c (init_child_ops): Likewise.
+       * m3-nat.c (init_m3_ops): Likewise.
+       * procfs.c (init_procfs_ops): Likewise.
+       * wince.c (init_child_ops): Likewise.
+       * win32-nat.c (init_child_ops): Likewise.
+       * sol-thread.c (init_sol_thread_ops): Likewise.
+
+2002-08-26  Mark Kettenis  <kettenis@gnu.org>
+
+       * i386-tdep.c (i386_store_return_value): Undeprecate.  Convert to
+       use regcache_* functions.
+       (i386_gdbarch_init): Set store_return_value instead of
+       deprecated_store_return_value.
+
+       * regcache.c (regcache_raw_write_signed,
+       regcache_raw_write_unsigned): New functions.
+       * regcache.h (regcache_raw_write_signed,
+       regcache_raw_write_unsigned): New prototypes.
+
+2002-08-25  Andrew Cagney  <ac131313@redhat.com>
+
+       * Makefile.in (c-exp.tab.o, jv-exp.tab.o, f-exp.tab.o)
+       (m2-exp.tab.o, p-exp.tab.o, ada-exp.tab.o): Move to before the
+       source file dependencies.  Cleanup corresponding generator rules.
+
+2002-08-25  Andrew Cagney  <ac131313@redhat.com>
+
+       * regcache.h (register_offset_hack): Declare.
+       (regcache_cooked_read_using_offset_hack): Declare.
+       (regcache_cooked_write_using_offset_hack): Declare.
+
+       * regcache.c (register_offset_hack): New function.
+       (regcache_cooked_read_using_offset_hack): New function.
+       (regcache_cooked_write_using_offset_hack): New function.
+       (regcache_dump): Check that the registers, according to their
+       offset, are packed hard against each other.
+       (cooked_xfer_using_offset_hack): New function.
+
+2002-08-25  Andrew Cagney  <ac131313@redhat.com>
+
+       * regcache.c (struct regcache_descr): Add field register_type.
+       (init_legacy_regcache_descr): Pass a pre-allocated regcache_descr
+       in as a parameter
+       (init_regcache_descr): Initialize register_type.  Pass the descr
+       to init_legacy_regcache_descr.  Use register_type instead of
+       REGISTER_VIRTUAL_TYPE.
+       (register_type): New function.
+       (regcache_dump): Replace REGISTER_VIRTUAL_TYPE with register_type.
+       * regcache.h (register_type): Declare.
+
+2002-08-25  Andrew Cagney  <ac131313@redhat.com>
+
+       * rs6000-tdep.c (rs6000_gdbarch_init): Set store_struct_return
+       instead of deprecated_store_return_value.  Fix fallout from
+       2002-08-23 Andrew Cagney <cagney@redhat.com>.
+
+2002-08-25  Andrew Cagney  <ac131313@redhat.com>
+
+       * regcache.c (max_register_size): New function.
+       (init_legacy_regcache_descr): Ensure that max_register_size is
+       large enough for REGISTER_VIRTUAL_SIZE.
+       * regcache.h (max_register_size): Declare.
+
+2002-08-24  Andrew Cagney  <ac131313@redhat.com>
+
+       * rs6000-tdep.c (rs6000_gdbarch_init): Use deprecated version of
+       store_return_value.
+       (e500_extract_return_value): Change type of valbuf pointer to
+       void.
+
+2002-08-24  Mark Kettenis  <kettenis@gnu.org>
+
+       * PROBLEMS: Clarify problems with FreeBSD's compiler and suggest
+       workaround.
+
+       * valprint.c (print_longest) [CC_HAS_LONG_LONG &&
+       PRINTF_HAS_LONG_LONG]: Cast val_long to (long long) or (unsigned
+       long long) to prevent compiler warning on 64-bit systems.
+
+2002-08-23  Andrew Cagney  <cagney@redhat.com>
+
+       * gdbarch.sh (STORE_RETURN_VALUE): Add regcache parameter.
+       (DEPRECATED_STORE_RETURN_VALUE): New method.
+       (EXTRACT_RETURN_VALUE): Make buffer parameter a void pointer.
+       * gdbarch.h, gdbarch.c: Re-generate.
+
+       * values.c (set_return_value): Pass current_regcache to
+       STORE_RETURN_VALUE.
+       * arch-utils.h (legacy_store_return_value): Declare.
+       * arch-utils.c (legacy_store_return_value): New function.
+       (legacy_extract_return_value): Update parameters.
+
+       * config/pa/tm-hppa.h (DEPRECATED_STORE_RETURN_VALUE): Rename
+       STORE_RETURN_VALUE.
+       * config/pa/tm-hppa64.h (DEPRECATED_STORE_RETURN_VALUE): Ditto.
+       * config/sparc/tm-sparc.h (DEPRECATED_STORE_RETURN_VALUE): Ditto.
+       * config/z8k/tm-z8k.h (DEPRECATED_STORE_RETURN_VALUE): Ditto.
+       * config/sparc/tm-sparclet.h (DEPRECATED_STORE_RETURN_VALUE): Ditto.
+       * config/mn10200/tm-mn10200.h (DEPRECATED_STORE_RETURN_VALUE): Ditto.
+       * config/m68k/tm-linux.h (DEPRECATED_STORE_RETURN_VALUE): Ditto.
+       * config/m68k/tm-delta68.h (DEPRECATED_STORE_RETURN_VALUE): Ditto.
+       * config/m32r/tm-m32r.h (DEPRECATED_STORE_RETURN_VALUE): Ditto.
+       * config/h8500/tm-h8500.h (DEPRECATED_STORE_RETURN_VALUE): Ditto.
+       * config/h8300/tm-h8300.h (DEPRECATED_STORE_RETURN_VALUE): Ditto.
+
+       * m68hc11-tdep.c (m68hc11_gdbarch_init): Update.
+       * i386-tdep.c (i386_extract_return_value): Update.
+       * arch-utils.c (legacy_extract_return_value): Update.
+       * frv-tdep.c (frv_gdbarch_init): Update.
+       * cris-tdep.c (cris_gdbarch_init): Update.
+       * d10v-tdep.c (d10v_gdbarch_init): Update.
+       * rs6000-tdep.c (rs6000_gdbarch_init): Update.
+       * m68k-tdep.c (m68k_gdbarch_init): Update.
+       * mcore-tdep.c (mcore_gdbarch_init): Update.
+       * mn10300-tdep.c (mn10300_gdbarch_init): Update.
+       * s390-tdep.c (s390_gdbarch_init): Update.
+       * sparc-tdep.c (sparc_gdbarch_init): Update.
+       * sh-tdep.c (sh_gdbarch_init): Update.
+       * x86-64-tdep.c (x86_64_gdbarch_init): Update.
+       * v850-tdep.c (v850_gdbarch_init): Update.
+       * avr-tdep.c (avr_gdbarch_init): Update.
+       * ia64-tdep.c (ia64_gdbarch_init): Update.
+       * ns32k-tdep.c (ns32k_gdbarch_init): Update.
+       * vax-tdep.c (vax_gdbarch_init): Update.
+       * alpha-tdep.c (alpha_gdbarch_init): Update.
+       * arm-tdep.c (arm_gdbarch_init): Update.
+       * mips-tdep.c (mips_gdbarch_init): Update.
+       * i386-tdep.c (i386_gdbarch_init): Update.
+
+2002-08-23  Andrew Cagney  <ac131313@redhat.com>
+
+       * config/djgpp/fnchange.lst: Add entries for bfd/elf32-ppcqnx.c,
+       bfd/elf32-ppc.c, bfd/elf32-sh.c and bfd/elf32-shqnx.c.
+
+2002-08-24  Mark Kettenis  <kettenis@gnu.org>
+
+       * PROBLEMS: Refer to GDB 5.3 instead of 5.2.  Mention FreeBSD
+       problems.
+
+2002-08-23  Joel Brobecker  <brobecker@gnat.com>
+
+       * infrun.c (handle_inferior_event): Move a comment outside of a
+       function call, in order to avoid indent reformatting this part
+       of the code in an unreadable way.
+
+2002-08-23  Grace Sainsbury  <graces@redhat.com>
+
+       * infrun.c (normal_stop, proceed): Remove call to print_sys_errmsg
+       when breakpoints fail. Move general breakpoint error messages to
+       insert_breakpoints.  
+       * breakpoint.c (insert_breakpoints): Change warnings when
+       breakpoints are nto inserted to specify the type. Remove call to
+       memory_error when hardware breakpoints can't be inserted. Remove
+       multiple calls to warning so all messages are sent to the user at
+       once.
+       (delete_breakpoints): Make insert error messsages more explicit.
+
+2002-08-23  Daniel Jacobowitz  <drow@mvista.com>
+
+       * ChangeLog: Move gdbserver entries after GDB 5.2 to
+       gdbserver/ChangeLog.
+
+2002-08-23  Mark Kettenis  <kettenis@gnu.org>
+
+       * i386-tdep.c: Include "objfiles.h".
+       (i386_svr4_init_abi): Set in_solib_call_trampoline and
+       skip_trampoline_code.
+       * config/i386/tm-i386v4.h: Don't include "config/tm-sysv4.h".
+       (CPLUS_MARKER): Define to '.'.
+
+       * linux-proc.c (struct linux_corefile_thread_data): Add num_notes
+       member.
+       (linux_corefile_thread_callback): Increase args->num_notes.
+       (linux_make_note_section): Initialize thread_args.num_notes, and
+       use it to determine whether notes for any threads were created.
+
+2002-08-23  Donn Terry  <donnte@microsoft.com>
+
+       * proc-api.c (rw_table): Do not include a row for PCDSTOP if the
+       corresponding macro is not defined. Likewise for PCNICE, PCSHOLD
+       and PCUNKILL.
+       (write_with_trace): Conditionalize out the switch branch handling
+       PCSHOLD if the corresponding macro is not defined. Likewise for
+       PRSABORT and PRSTOP.
+       This change will be needed by the Interix port.
+
+2002-08-22  Elena Zannoni  <ezannoni@redhat.com>
+
+       * ppc-sysv-tdep.c (ppc_sysv_abi_push_arguments): use
+       write_register wherever possible instead of manipulating the
+       register bytes directly.
+       Assign VALUE_CONTENTS to a variable and use that.
+       The GPR numbers are now dependent on the architecture.
+       
+2002-08-22  Elena Zannoni  <ezannoni@redhat.com>
+
+       * rs6000-tdep.c (struct rs6000_framedata): Add saved_ev and
+       ev_offset fields.
+       (skip_prologue): Add support for BookE/e500 instructions.
+       (e500_extract_return_value): New function.
+       (frame_get_saved_regs): Add support for saving ev registers and
+       pseudo gpr's.
+       (e500_store_return_value): New function.
+       (rs6000_gdbarch_init): Move up default intializations of
+       deprecated_extract_return_value and store_return_value.  Overwrite
+       init of store_return_value with e500 specific version.
+       Set extract_return_value for e500.
+       
+2002-08-22  Elena Zannoni  <ezannoni@redhat.com>
+
+       * blockframe.c (generic_call_dummy_register_unwind): Use
+       regcache_cooked_read to catch cases in which the variable is
+       stored in a pseudo register.
+
+2002-08-22  Andrew Cagney  <cagney@redhat.com>
+
+       * NEWS: Mention that the i960 has been made obsolete.
+       * Makefile.in (SFILES): Delete remote-nrom.c, remote-nindy.c and
+       i960-tdep.c
+       (remote-nrom.o): Obsolete target.
+       (remote-nindy.o, i960-tdep.o): Ditto.
+       * remote-nrom.c: Make file obsolete.
+       * remote-nindy.c, remote-vx960.c: Ditto.
+       * config/i960/vxworks960.mt, config/i960/nindy960.mt: Ditto.
+       * config/i960/mon960.mt, config/i960/tm-i960.h: Ditto.
+       * config/i960/tm-vx960.h, config/i960/tm-nindy960.h: Ditto.
+       * config/i960/tm-mon960.h, i960-tdep.c: Ditto.
+       * configure.tgt: Make i960-*-bout*, i960-nindy-coff*,
+       i960-*-coff*, i960-nindy-elf*, i960-*-elf*, i960-*-nindy* and
+       i960-*-vxworks* obsolete.
+       * MAINTAINERS: Note that the i960 is obsolete.
+
+2002-08-21  Corinna Vinschen  <vinschen@redhat.com
+
+       * aix-thread.c (aix_thread_detach): Disable thread debugging on
+       detach to allow reinitialization.
+
+2002-08-22  Andrew Cagney  <ac131313@redhat.com>
+
+       * MAINTAINERS: Change the s390 target to s390-linux-gnu (second
+       attempt).
+
+2002-08-22  Jim Blandy  <jimb@redhat.com>
+
+       * coffread.c (coff_symfile_read): Don't try to read the line
+       number table from disk if the image file doesn't have a symbol
+       table; we'll never actually look at the info anyway, and Windows
+       ships DLL's with bogus file offsets for the line number data.
+
+2002-08-21  Elena Zannoni  <ezannoni@redhat.com>
+
+        * rs6000-tdep.c (rs6000_gdbarch_init): Figure out whether we have
+        an e500 executable.
+
+2002-08-21  Michael Snyder  <msnyder@redhat.com>
+
+       * mips-tdep.c (MSYMBOL_IS_SPECIAL): Replace macro with function.
+       (MSYMBOL_SIZE): Replace macro with function.
+       (DEFAULT_MIPS_TYPE): Delete unused macro.
+       * config/mips/tm-mips.h (DEFAULT_MIPS_TYPE): Delete unused macro.
+       * config/mips/tm-embed.h (DEFAULT_MIPS_TYPE): Delete unused macro.
+
+2002-08-21  Jim Blandy  <jimb@redhat.com>
+
+       * valops.c (value_cast): Simplify and correct logic for doing a
+       static cast from a pointer to a base class to a pointer to a
+       derived class.
+
+2002-08-21  Andrew Cagney  <ac131313@redhat.com>
+
+       * infcmd.c (default_print_registers_info): Replace
+       do_registers_info.
+       (registers_info): Use gdbarch_print_registers_info instead of
+       DO_REGISTERS_INFO.
+       * inferior.h (default_print_registers_info): Replace
+       do_registers_info.
+       * gdbarch.sh (PRINT_REGISTERS_INFO): New method.
+       (DO_REGISTERS_INFO): Change to a predicate function.
+       * gdbarch.h, gdbarch.c: Regenerate.
+       
+2002-08-21  Keith Seitz  <keiths@redhat.com>
+
+       * gdb-events.sh: Add target-changed event.
+       * gdb-events.c: Regenerated.
+       * gdb-events.c: Regenerated.
+       * valops.c (value_assign): Add target-changed event notification
+       to inlval_register, lval_memory, and lval_reg_frame_relative.
+
+2002-08-21  Joel Brobecker  <brobecker@gnat.com>
+
+       * NEWS: Add an entry regarding the improvement of the next/step
+       operation on Alpha Tru64 multi-processor machines.
+
+2002-08-21  Andrew Cagney  <ac131313@redhat.com>
+
+       * Makefile.in: Update dependencies for mi/ cli/ and tui/
+       directores.
+       * Makefile.in: Update all _h macro definitions.
+       * Makefile.in (install-gdbtk): Move to install section.
+       (rdi-share/libangsd.a): Move to end of file.
+
+2002-08-19  Andrew Cagney  <ac131313@redhat.com>
+
+       * frame.c (frame_register_unwind): When a register, set addrp to
+       the register's byte.
+
+2002-08-20  Michael Snyder  <msnyder@redhat.com>
+
+       * mips-tdep.c (MSYMBOL_IS_SPECIAL, MSYMBOL_SIZE): These are only
+       used locally, so move them from the target machine header to here.
+       (mips_set_processor_type, mips_register_name, mips32_next_pc, 
+       mips16_next_pc, cached_proc_desc, mips_set_processor_type): 
+       Make static.
+       * config/mips/tm-mips.h (MSYMBOL_IS_SPECIAL, MSYMBOL_SIZE): Delete.
+
+2002-08-20  Andrew Cagney  <cagney@redhat.com>
+
+       * NEWS: Mention that the Apollo line was made obsolete.
+       * configure.tgt: Make m68*-apollo*-bsd*, m68*-hp-bsd*, and
+       m68*-hp-hpux* obsolete.
+       * configure.host: Make m68*-apollo*-sysv*, m68*-apollo*-bsd*,
+       m68*-hp-bsd* and m68*-hp-hpux* obsolete.
+       * buildsym.c (make_blockvector): Make static.
+       * buildsym.h (make_blockvector): Make extern declaration obsolete.
+       * Makefile.in (HFILES_NO_SRCDIR): Remove dst.h
+       (ALLDEPFILES): Remove dstread.c.
+       (dstread.o): Obsolete make rule.
+       * dstread.c: Makefile obsolete.
+       * dst.h: Ditto.
+       * config/m68k/hp300hpux.mt: Ditto.
+       * config/m68k/hp300hpux.mh: Ditto.
+       * config/m68k/hp300bsd.mt: Ditto.
+       * config/m68k/hp300bsd.mh: Ditto.
+       * config/m68k/apollo68b.mt: Ditto.
+       * config/m68k/apollo68v.mh: Ditto.
+       * config/m68k/apollo68b.mh: Ditto.
+
+2002-08-20  Michael Snyder  <msnyder@redhat.com>
+
+       * mips-tdep.c (mips_in_return_stub): Make static.
+       (mips_gdbarch_init): Set in_solib_return_trampoline.
+       * config/mips/tm-mips.h (IN_SOLIB_RETURN_TRAMPOLINE): Delete.
+
+2002-08-20  Michael Snyder  <msnyder@redhat.com>
+
+       * gdbarch.sh (IN_SOLIB_RETURN_TRAMPOLINE): Add.
+       * gdbarch.c, gdbarch.h: Regenerate.
+       * arch-utils.c, arch-utils.h (generic_in_solib_return_trampoline):
+       Add.
+       * infrun.c (IN_SOLIB_RETURN_TRAMPOLINE): Delete default definition.
+
+2002-08-20  Michael Snyder  <msnyder@redhat.com>
+
+       * mips-tdep.c (mips_skip_stub, mips_in_call_stub): Make static.
+       (mips_gdbarch_init): Set skip_trampoline_code, 
+       in_solib_call_trampoline.
+       * config/mips/tm-mips.h (REGISTER_NAME): Delete.
+       (IN_SOLIB_CALL_TRAMPOLINE, SKIP_TRAMPOLINE_CODE): Delete.
+
+2002-08-20  Elena Zannoni  <ezannoni@redhat.com>
+
+       * ppc-tdep.h (struct gdbarch_tdep): Add ev registers.
+
+       * rs6000-tdep.c (rs6000_register_virtual_type): Return 64 bit
+       vector type for ev registers.
+       (e500_pseudo_register_read): New function.
+       (e500_pseudo_register_write): New function.
+       (e500_dwarf2_reg_to_regnum): New function.
+       (PPC_UISA_NOFP_SPRS): New macro.
+       (PPC_EV_REGS): New macro.
+       (PPC_GPRS_PSEUDO_REGS): New macro.
+       (registers_e500): New register set for e500.
+       (variants): Add e500 variant.
+       (rs6000_gdbarch_init): Move setting of pc, sp, fp regnums to
+       before setting architectural dependent variations.  Initialize ev
+       registers numbers.  Add case for e500 architecture.  Set the
+       number of pseudo registers.
+
+2002-08-20  Elena Zannoni  <ezannoni@redhat.com>
+
+        * rs6000-tdep.c: Clean up comments.
+
+2002-08-20  Andrew Cagney  <cagney@redhat.com>
+
+       * h8300-tdep.c: Re-indent file.
+
+2002-08-20  Jim Blandy  <jimb@redhat.com>
+
+       * Makefile.in (LDFLAGS): Allow the configure script to establish a
+       default for this.
+
+2002-08-20  Keith Seitz  <keiths@redhat.com>
+
+       * breakpoints.c (watch_command_1): Use internal breakpoint
+       when setting a watchpoint_scope breakpoint.
+
+2002-08-20  Elena Zannoni  <ezannoni@redhat.com>
+
+        * gdbtypes.c (build_builtin_type_vec64): Add name to type.
+        (build_builtin_type_vec64i): Ditto.
+        (build_builtin_type_vec128): Ditto.
+        (build_builtin_type_vec128i): Ditto.
+
+2002-08-19  Michael Snyder  <msnyder@redhat.com>
+
+       * config/mips/tm-mips.h (ELF_MAKE_MSYMBOL_SPECIAL): Delete.
+       (MSYMBOL_IS_SPECIAL, MSYMBOL_SIZE): Change into functions.
+       (FIX_CALL_DUMMY, PUSH_RETURN_ADDRESS, PUSH_DUMMY_FRAME,
+       POP_FRAME, INIT_EXTRA_FRAME_INFO): Delete.
+       (CALL_DUMMY_START_OFFSET, CALL_DUMMY_BREAKPOINT_OFFSET,
+       CALL_DUMMY_ADDRESS): Delete.
+       * mips-tdep.c (mips_elf_make_msymbol_special, mips_msymbol_size,
+       mips_msymbol_is_special, mips_fix_call_dummy): New functions.
+       (mips_gdbarch_init): Set elf_make_msymbol_special, pop_frame, 
+       push_dummy_frame, fix_call_dummy, init_extra_frame_info, 
+       push_return_address.
+       (mips_register_raw_size, mips_eabi_use_struct_convention, 
+       mips_n32n64_use_struct_convention, mips_o32_use_struct_convention,
+       mips_o32_reg_struct_has_addr, mips_frame_saved_pc, mips_frame_chain,
+       mips_init_extra_frame_info, mips_eabi_push_arguments, 
+       mips_n32n64_push_arguments, mips_push_return_address,
+       mips_push_dummy_frame, mips_pop_frame, mips_skip_prologue,
+       mips_breakpoint_from_pc, mips_call_dummy_address): Make static.
+
+2002-08-19  Michael Snyder  <msnyder@redhat.com>
+
+       * mips-tdep.c (mips_frame_num_args): New function.
+       (mips_gdbarch_init): Set frame_chain, frameless_function_invocation,
+       frame_saved_pc, frame_args_address, frame_locals_address, 
+       frame_num_args, and frame_args_skip.
+       * config/mips/tm-mips.h (FRAME_CHAIN, FRAMELESS_FUNCTION_INVOCATION,
+       FRAME_SAVED_PC, FRAME_ARGS_ADDRESS, FRAME_LOCALS_ADDRESS, 
+       FRAME_NUM_ARGS, FRAME_ARGS_SKIP): Delete.
+       * config/mips/tm-mipsv4.h (FRAME_CHAIN_VALID): Delete.
+
+2002-08-20  Michael Snyder  <msnyder@redhat.com>
+
+       * config/mips/tm-mips.h (STORE_STRUCT_RETURN): Delete.
+       (EXTRACT_STRUCT_VALUE_ADDRESS): Delete.
+       * mips-tdep.c (mips_store_struct_return): New function.
+       (mips_extract_struct_value_address): New function.
+       (mips_gdbarch_init): Set store_struct_return and
+       extract_struct_value_address.
+
+2002-08-20  David Carlton  <carlton@math.stanford.edu>
+
+       * dwarf2read.c (dwarf2_build_psymtabs): Check that
+       dwarf_line_offset is nonzero before creating dwarf_line_buffer.
+       (read_file_scope): Check that line_header is nonzero before
+       decoding macro information.
+
+2002-08-20  Mark Kettenis  <kettenis@gnu.org>
+
+       * i386-tdep.h (FP_REGNUM_P): Change such that we don't incorrectly
+       flag the general-purpose registers as floating-point on targets
+       that don't support the floating-point registers.
+
+2002-08-20  Elena Zannoni  <ezannoni@redhat.com>
+
+       * rs6000-tdep.c (altivec_register_p): Delete.
+       (rs6000_do_altivec_registers): Delete.
+       (rs6000_altivec_registers_info): Delete.
+       (rs6000_do_registers_info): Delete.
+       (_initialize_rs6000_tdep): Remove command 'info powerpc altivec'.
+       (rs6000_gdbarch_init): Remove setting of do_registers_info.
+
+2002-08-20  Elena Zannoni  <ezannoni@redhat.com>
+
+       * infcmd.c (do_registers_info): Print vector registers in hex
+       format only.
+       (print_vector_info): Check that printing registers
+       makes sense.
+       (print_float_info): Ditto.
+
+2002-08-20  Andrew Cagney  <ac131313@redhat.com>
+
+       * mips-tdep.c (mips_gdbarch_init): Update.
+       (mips_o32_extract_return_value): Rewrite.
+       (mips_o32_store_return_value): Rewrite.
+       (mips_o32_xfer_return_value): New function.
+       (mips_xfer_register): Tweak debug print message.  Allow for
+       buf_offset when dumping the value transfered.
+
+2002-08-20  Andrew Cagney  <ac131313@redhat.com>
+
+       * config/mips/tm-nbsd.h (MIPS_DEFAULT_ABI): Delete.
+       * config/mips/tm-linux.h (MIPS_DEFAULT_ABI): Delete.
+       * config/mips/tm-irix5.h (MIPS_DEFAULT_ABI): Delete.
+       * config/mips/tm-irix6.h (MIPS_DEFAULT_ABI): Delete.
+       * mips-tdep.c (mips_gdbarch_init) [MIPS_DEFAULT_ABI]: Delete code.
+
+2002-08-14  Michael Snyder  <msnyder@redhat.com>
+
+       * mips-tdep.c (mips_frame_chain): Check for call-dummy frames.
+
+2002-08-19  Elena Zannoni  <ezannoni@redhat.com>
+
+       * rs6000-tdep.c (struct reg): Add field to indicate a pseudo
+       register.
+       (P): New macro to define a register as a pseudo register.
+       (R, R4, R8, R16, FR32, R64, R0): Updated.
+       (struct variant): Add new fields for number of pseudo registers
+       and number of total registers.
+       (tot_num_registers): New macro replacing....
+       (num_registers): ...deleted macro.
+       (num_registers): New function.
+       (num_pseudo_registers): New function.
+       (variants): Update all variants to intialize new fields correctly.
+       Postpone initialization of number of pseudo regs and real regs.
+       (init_variants): New function.
+       (rs6000_gdbarch_init): Initialize variants.  Update calculation of
+       registers offsets.
+
+2002-08-19  David Carlton  <carlton@math.stanford.edu>
+
+       * valops.c (search_struct_field): Change error message to treat
+       return value of 0 from value_static_field as meaning that field is
+       optimized out.
+       (value_struct_elt_for_reference): Ditto.
+       * values.c (value_static_field): Treat an unresolved location the
+       same as a nonexistent symbol.  Fix PR gdb/635.
+       * gnu-v2-abi.c (gnuv2_value_rtti_type): Eliminate test for being
+       enclosed.  Fix PR gdb/574.
+       * MAINTAINERS: Add self to Write After Approval list.
+
+2002-08-19  Andrew Cagney  <ac131313@redhat.com>
+
+       * mips-tdep.c (mips_xfer_register): New function.
+       (mips_n32n64_extract_return_value): Rewrite.
+       (mips_gdbarch_init): For N32 and N64, set extract_return_value
+       instead of deprecated_extract_return_value.
+
+2002-08-19  Elena Zannoni  <ezannoni@redhat.com>
+
+       * rs6000-tdep.c (TDEP): Delete macro.
+       (branch_dest): Replace use of TDEP macro with its body.
+       (rs6000_pop_frame): Ditto.
+       (rs6000_push_arguments): Ditto.
+       (rs6000_skip_trampoline_code): Ditto.
+       (rs6000_frame_saved_pc): Ditto.
+       (rs6000_frame_chain): Ditto.
+       (rs6000_register_name): Ditto.
+       (rs6000_register_byte): Ditto.
+        (rs6000_register_raw_size): Ditto.
+       (rs6000_register_virtual_type): Ditto.
+       (rs6000_register_convertible): Ditto.
+       (rs6000_convert_from_func_ptr_addr): Ditto.
+
+2002-08-19  Daniel Jacobowitz  <drow@mvista.com>
+
+       * config/mips/tm-linux.h (REALTIME_LO, REALTIME_HI): Define
+       conditionally.
+       (JB_PC, JB_ELEMENT_SIZE): Rename to MIPS_LINUX_JB_PC and
+       MIPS_LINUX_JB_ELEMENT_SIZE.
+       * mips-linux-tdep.c (supply_gregset, fill_gregset): Use alloca
+       for MAX_REGISTER_RAW_SIZE arrays.
+       (mips_linux_get_longjmp_target): Use MIPS_LINUX_JB_PC and
+       MIPS_LINUX_JB_ELEMENT_SIZE.
+
+2002-08-19  Pierre Muller  <muller@ics.u-strasbg.fr>
+
+       * i387-tdep.c (i387_print_float_info): Fix typo in comment.
+
+2002-08-19  Aidan Skinner <aidan@velvet.net>
+
+       * Makefile.in (SFILES): Add ada-exp.y ada-lang.c ada-typeprint.c
+       ada-valprint.c ada-tasks.c.
+       (YYFILES): Add ada-exp.y.
+       (ada-exp.tab.c ada-lex.c ada-lang.o): New target.
+       (ada-tasks.o ada-typeprint.o ada-valprint.o): New target.
+       (ada-exp.tab.o): New target.
+               
+2002-08-18  Andrew Cagney  <ac131313@redhat.com>
+
+       * regcache.c (regcache_xfer_part): New function.
+       (regcache_raw_read_part): New function.
+       (regcache_raw_write_part): New function.
+       (regcache_cooked_read_part): New function.
+       (regcache_cooked_write_part): New function.
+       * regcache.h (regcache_raw_read_part): Declare.
+       (regcache_raw_write_part): Declare.
+       (regcache_cooked_read_part): Declare.
+       (regcache_cooked_write_part): Declare.
+
+2002-08-18  Daniel Jacobowitz  <drow@mvista.com>
+
+       * remote.c (remote_open_1): Add async_p.
+       (remote_async_open_1): Delete.
+       (open_remote_target): Delete.
+       (remote_open, extended_remote_open): Update calls to remote_open_1.
+       (remote_async_open, extended_remote_async_open): Call
+       remote_open_1 instead of remote_async_open_1.
+
+2002-08-19  Mark Kettenis  <kettenis@gnu.org>
+
+       * blockframe.c: Fix a few coding standard violations.
+
+2002-08-19  Mark Kettenis  <kettenis@gnu.org>
+
+       * config/i386/nm-i386sco5.h (START_INFERIOR_TRAPS_EXPECTED): Moved
+       here from ...
+       * config/i386/tm-i386sco5.h: ... here.  File removed.
+       * config/i386/i386sco5.mt (TM_FILE): Set to tm-i386v4.h.
+
+       * config/i386/nm-i386v.h (START_INFERIOR_TRAPS_EXPECTED): New define.
+       * config/i386/i386aout.mt (TDEPFILES): Add i387-tdep.o
+       (TM_FILE): Set to tm-i386.h.
+       * config/i386/i386v.mt (TM_FILE): Set to tm-i386.h.
+       * config/i386/tm-i386v.h: Remove file.
+       * config/i386/tm-ptx.h [!SEQUENT_PTX4]: Include "i386/tm-i386.h"
+       instead of "i386/tm-i386v.h".
+       (START_INFERIOR_TRAPS_EXPECTED): Remove define.
+       * config/i386/tm-symmetry: Include "i386/tm-i386.h" instead of
+       "i386/tm-i386v.h".
+       (START_INFERIOR_TRAPS_EXPECTED): Remove define.
+       * config/i386/tm-vxworks.h: Include "i386/tm-i386.h" instead of
+       "i386/tm-i386.h".
+
+2002-08-18  Mark Kettenis  <kettenis@gnu.org>
+
+       * config/i386/nm-i386v.h: Add protection against
+       multiple-inclusion.
+       (i386_register_u_addr): Remove prototype.
+       (register_u_addr): New prototype.
+       (REGISTER_U_ADDR): Redefine accordingly.
+       * i386v-nat.c: Improve several comments.
+       (i386_register_u_addr): Change signature and rename to
+       register_u_addr.  Use FP_REGNUM_P.  Rewrite slightly to get rid of
+       ubase variable.
+
+2002-08-18  Andrew Cagney  <ac131313@redhat.com>
+
+       * config/mips/tm-mips.h (STORE_RETURN_VALUE): Delete macro.
+       (DEPRECATED_EXTRACT_RETURN_VALUE): Delete macro.
+       * mips-tdep.c (mips_gdbarch_init): Set store_return_value and
+       deprecated_extract_return_value.
+       (mips_o32_push_arguments, mips_o64_push_arguments): Clone and
+       rename mips_o32o64_push_arguments.
+       (mips_gdbarch_init): Update.
+       (mips_extract_return_value): Delete.
+       (mips_o32_extract_return_value): Clone mips_extract_return_value.
+       (mips_o64_extract_return_value): Clone mips_extract_return_value.
+       (mips_eabi_extract_return_value): Clone mips_extract_return_value.
+       (mips_n32n64_extract_return_value): Clone
+       mips_extract_return_value.
+       (mips_store_return_value): Delete.
+       (mips_o32_store_return_value): Clone mips_store_return_value.
+       (mips_o64_store_return_value): Clone mips_store_return_value.
+       (mips_eabi_store_return_value): Clone mips_store_return_value.
+       (mips_n32n64_store_return_value): Clone mips_store_return_value.
+
+2002-08-18  Aidan Skinner <aidan@velvet.net>
+
+       * ada-lang.c: Use gdb_string.h instead of <string.h>.
+       * ada-typeprint.c: Use gdb_string.h instead of <string.h>.
+               
+2002-08-18  Aidan Skinner <aidan@velvet.net>
+
+        * ada-lang.c: Run through gdb_indent.sh.
+        * ada-lang.h: Run through gdb_indent.sh.
+        * ada-tasks.c: Run through gdb_indent.sh.
+        * ada-typeprint.c: Run through gdb_indent.sh.
+        * ada-valprint.c: Run through gdb_indent.sh.
+
+2002-08-18  Andrew Cagney  <ac131313@redhat.com>
+
+       * osabi.c (gdbarch_init_osabi): Don't complain about an unknown
+       ABI.
+
+2002-08-18  Mark Kettenis  <kettenis@gnu.org>
+
+       * i386b-nat.c [FETCH_INFERIOR_REGISTERS]: Remove dead code.
+
+       * config/i386/nm-i386bsd.h (FLOAT_INFO): Remove redundant #undef.
+       * i386b-nat.c [FLOAT_INFO]: Remove dead code.
+
+       * i386-tdep.c (i386_do_pop_frame, i386_store_return_value): Call
+       write_register_gen instead of write_register_bytes.
+
+       * NEWS: Mention that the i[3456]-*mach3*, i[3456]-*-mach* and
+       i[3456]-*-osf1mk* configurations have been made obsolete.
+       * configure.host: Make i[3456]86-*-mach3*, i[3456]86-*mach* and
+       i[3456]86-*-osf1mk* hosts obsolete.
+       * confighure.tgt: Make i[3456]86-*-mach3*, i[3456]86-*-osf1mk*
+       targets obsolete.
+       * config/i386/i386mach.mh, config/i386/nm-i386mach.h,
+       config/i386/xm-i386mach.h, config/i386/i386m3.mh,
+       config/i386/i386m3.mt, config/i386/nm-m3.h,
+       config/i386/tm-i386m3.h, config/i386/xm-i386m3.h,
+       config/i386/i386mk.mh, config/i386/i386mk.mt,
+       config/i386/tm-i386mk.h, config/i386/xm-i386mk.h: Make files
+       obsolete.
+       * i386mach-nat.c, i386m3-nat.c: Make files obsolete.
+       * Makefile.in (ALLDEPFILES): Remove i386mach.c i386m3-nat.c
+       (i386mach-nat.o, i386m3-nat.o):Make targets obsolete.
+
+2002-08-18  Andrew Cagney  <ac131313@redhat.com>
+
+       * config/pa/tm-hppa.h (hppa_store_return_value): Declare.
+       (hppa_value_returned_from_stack): Declare.
+       (hppa_extract_return_value): Declare.
+       * config/pa/hppa.mt: New file.
+       * configure.tgt: Recognize hppa*-*-*.
+       * MAINTAINERS: Change HPPA target to hppa-elf.  Still broken.
+
+2002-08-18  Mark Kettenis  <kettenis@gnu.org>
+
+       * i386-sol2-tdep.c (_initialize_i386_sol2_tdep): Fix typo in
+       comment.
+
+2002-08-17  Mark Kettenis  <kettenis@gnu.org>
+
+       * top.c (gdb_rl_operate_and_get_next): Make sure
+       operate-and-get-next functions correctly even when the history
+       list is completely filled.
+
+2002-08-18  Andrew Cagney  <ac131313@redhat.com>
+
+       * MAINTAINERS (Target Instruction Set Architectures): Rename
+       Target/Architectures.  Replace vax-dec-vms5.5 with vax-netbsd.
+       Replace s390-linux with s390-linux-gnu.  Remove i386-aout,
+       mcore-pe, mips64-elf, sparc64-elf.  Remove i586-pc-msdosdjgpp,
+       already listed under Host/Native.
+
+       * configure.tgt: Combine i[3456]86-*-coff*, i[3456]86-*-elf*,
+       i[3456]86-*-pe*, and i[3456]86-*-aout* into i[3456]86-*-*.  Add
+       mips*-*-*.
+
+2002-08-17  Andrew Cagney  <ac131313@redhat.com>
+
+       * config/ia64/ia64.mt: New file.
+       * config/alpha/alpha.mt: New file.
+       * MAINTAINERS: Change the alpha target to alpha-elf and IA-64 to
+       ia64-linux-gnu.  Mention that ia64-elf is broken.
+       * configure.tgt: Add alpha*-*-* and ia64*-*-* patterns.
+
+2002-08-17  Mark Kettenis  <kettenis@elgar.kettenis.dyndns.org>
+
+       * i386-tdep.c (i386_svr4_init_abi, i386_nw_init_abi): Use
+       generic_func_frame_valid instead of func_frame_valid.
+
+2002-08-16  Joel Brobecker  <brobecker@gnat.com>
+
+       * alpha-osf1-tdep.c (alpha_osf1_init_abi): Unfortunately,
+       procfs appears to be broken when debugging on multi-processor
+       machines. So enable software single stepping in order to avoid
+       using the procfs interface to do next/step operations, using
+       internal breakpoints instead.
+
+       * infrun.c (handle_inferior_event): Readjust the stop_pc by
+       DECR_PC_AFTER_BREAK when hitting a single step breakpoint, to
+       make this pc address equal to the value it would have if the
+       system stepping capability was used. Also set a new flag used
+       to ensure that we don't readjust the PC one more time later.
+
+       * breakpoint.c (bpstat_stop_status): Do not adjust the PC
+       address by DECR_PC_AFTER_BREAK when software single step is
+       in use for this architecture, as this has already been taken
+       care of in handle_inferior_event().
+
+2002-08-16  Joel Brobecker  <brobecker@gnat.com>
+
+       * infrun.c (handle_inferior_event): Minor reformatting, to make
+       a rather long condition expression easier to read.
+
+2002-08-16  Andrew Cagney  <ac131313@redhat.com>
+
+       * Makefile.in (gdbtk.o): Move to end of file.
+       (gdbtk-bp.o, gdbtk-cmds.o): Ditto.
+       (gdbtk-hooks.o, gdbtk-register.o): Ditto.
+       (gdbtk-stack.o, gdbtk-varobj.o): Ditto.
+       (gdbtk-wrapper.o, gdbres.o): Ditto.
+
+2002-08-16  Andrew Cagney  <ac131313@redhat.com>
+
+       * Makefile.in (copying.o): Separate out compile rule.
+       (hpux-thread.o, procfs.o, signals.o): Ditto.
+       (v850ice.o, z8k-tdep.o): Ditto.
+       (tui-file.o): Move to TUI section.
+       (xdr_ptrace.o, xdr_rdb.o, xdr_ld.o): Move to separate section.
+       (nindy.o, Onindy.o, ttyflush.o): Move to separate section.
+
+2002-08-16  Joel Brobecker  <brobecker@gnat.com>
+
+       * i386-tdep.c (i386_pe_skip_trampoline_code): renamed from
+       skip_trampoline_code, for better namespace-proofing.   
+
+       * i386-tdep.h (i386_pe_skip_trampoline_code): Add declaration.
+
+2002-08-16  Joel Brobecker  <brobecker@gnat.com>
+
+       * config/i386/tm-cygwin.h: Remove some "#if 0"'ed macros.
+
+2002-08-16  Joel Brobecker  <brobecker@gnat.com>
+
+       * infrun.c (handle_inferior_event): When receiving a SIGTRAP
+       signal, check whether we hit a breakpoint before checking for a
+       single step breakpoint. Otherwise, GDB fails to notice that a
+       breakpoint has been hit when stepping onto a breakpoint.
+
+2002-08-16  Keith Seitz  <keiths@redhat.com>
+
+       * gdb-events.sh (clear_gdb_event_hooks): New function.
+       * gdb-events.c: Regenerate.
+       * gdb-events.h: Regenerate.
+
+2002-08-16  Andrew Cagney  <ac131313@redhat.com>
+
+       * breakpoint.c (bpstat_stop_status): Rename not_a_breakpoint to
+       not_a_sw_breakpoint.
+       * breakpoint.h (bpstat_stop_status): Add parameter names.
+
+2002-08-16  Grace Sainsbury  <graces@redhat.com>
+
+       * remote.c (remote_insert_hw_breakpoint)
+       (remote_remove_hw_breakpoint): Fix calculation of length field
+       for Z-packet.
+
+2002-08-15  Michael Snyder  <msnyder@redhat.com>
+
+       * irix5-nat.c (supply_gregset): Allocate plenty-big buffer
+       (32 bytes) instead of using MAX_REGISTER_RAW_SIZE.
+       (supply_fpregset): Ditto.
+       
+       * config/mips/tm-mips.h (REGISTER_CONVERT_TO_VIRTUAL, 
+       REGISTER_CONVERT_TO_RAW, REGISTER_CONVERTIBLE, 
+       MAX_REGISTER_RAW_SIZE, MAX_REGISTER_VIRTUAL_SIZE): Delete.
+       (TARGET_READ_SP): Delete.
+       (DO_REGISTERS_INFO): Delete.
+       (FUNCTION_START_OFFSET, IN_SIGTRAMP, REGISTER_VIRTUAL_SIZE):
+       Delete.
+       (REGISTER_CONVERT_FROM_TYPE, REGISTER_CONVERT_TO_TYPE): Convert
+       from macros to functions.
+
+       * mips-tdep.c (mips_gdbarch_init): Set the above in the gdbarch.
+       (mips_register_convertible, mips_register_convert_to_virtual,
+       mips_register_convert_to_raw): Make static.
+       (mips_read_sp): New function.
+       (mips_gdbarch_init): Set gdbarch read_sp to mips_read_sp.
+       (mips_do_registers_info): Make static.
+       (mips_gdbarch_init): Insert mips_do_registers_info into gdbarch.
+       (in_sigtramp): Make static, rename to mips_pc_in_sigtramp.
+       (mips_register_convert_from_type, mips_register_convert_to_type):
+       New functions.
+       (mips_gdbarch_init): Set up function_start_offset, 
+       register_virtual_size, pc_in_sigtramp.
+
+2002-08-15  Andrew Cagney  <ac131313@redhat.com>
+
+       * infcmd.c (vector_info): New function.
+       (_initialize_infcmd): Add command "info vector".
+       (print_vector_info): New function.
+
+       * gdbarch.sh (PRINT_VECTOR_INFO): New method
+       * gdbarch.h, gdbarch.c: Regenerate.
+
+2002-08-15  Andrew Cagney  <ac131313@redhat.com>
+
+       * infcmd.c (do_registers_info): Rename parameter ``fpregs'' to
+       ``print_all''.  Only print vector registers when ``print_all''.
+
+2002-08-15  Andrew Cagney  <ac131313@redhat.com>
+
+       * i387-tdep.h (i387_print_float_info): Add `args' parameter.
+       * i387-tdep.c (i387_print_float_info): Add `args' parameter.
+
+       * gdbarch.sh (PRINT_FLOAT_INFO): Change to a predicate method.
+       Add `args' parameter.
+       * gdbarch.h, gdbarch.c: Regenerate.
+       
+       * arm-tdep.c (arm_print_float_info): Add the parameter `args'.
+       
+       * infcmd.c (float_info): Call print_float_info.
+       (print_float_info): New function.  By default, print the
+       floating-point registers.
+
+       * arch-utils.h (default_print_float_info): Delete declaration.
+       * arch-utils.c (default_print_float_info): Delete function.
+       
+2002-08-16  Mark Kettenis  <kettenis@gnu.org>
+
+       * config/i386/nm-i386v.h (FLOAT_INFO): Remove already commented
+       out define.
+
+       * i387-tdep.c (i387_print_float_info): Add comment about ignoring
+       FRAME.
+
+       * NEWS: Mention that the i[3456]-*-aix target has been made obsolete.
+       * configure.host: Make i[3456]86-*-aix host obsolete.
+       * configure.tgt: Make i[3456]86-*-aix target obsolete.
+       * config/i386/i386aix.mh, config/i386/i386aix.mt,
+       config/i386/nm-i386aix.h, condig/i386/tm-i386aix.h,
+       config/i386/xm-i386aix.h: Make files obsolete.
+       * i386aix-nat.c: Make file obsolete.
+       * Makefile.in (ALLDEPFILES): Remove i386aix-nat.c.
+       (i386aix-nat.o): Make target obsolete.
+
+       * config/i386/nm-gnu.h: Removed.
+       * config/i386/nm-i386gnu.h: New file.
+       (THREAD_STATE_FLAVOR, THREAD_STATE_SIZE,
+       THREAD_STATE_SET_TRACED, THREAD_STATE_CLEAR_STATE, ATTACH_DETACH):
+       Moved here from ...
+       * config/i386/tm-i386gnu.h: ... here.  Removed.
+       * config/i386/xm-i386gnu.h: Removed.
+       * config/i386/i386gnu.mh (XM_FILE): Set to xm-i386.h.
+       (NAT_FILE): Set to nm-i386gnu.h.
+       * config/i386/i386gnu.mt (TDEPFILES): Add i386gnu-tdep.o.
+       * i386-tdep.c: New file.
+       * Makefile.in (ALLDEPFILES): Add i386gnu-nat.c and i386gnu-tdep.c.
+       (i386gnu-tdep.o): Specify dependencies.
+
+2002-08-15  Mark Kettenis  <kettenis@gnu.org>
+
+       * config/i386/tm-i386sco5.h: Include "i386/tm-i386v4.h" instead of
+       "i386/tm-i386.h", "i386/tm-i386v.h" and "config/tm-sysv.h".
+       Adjust a few comments to reflect reality a bit closer.
+       (KERNEL_U_SIZE, TARGET_HAS_HARDWARE_WATCHPOINTS,
+       TARGET_CAN_USE_HARDWARE_WATCHPOINT, HAVE_CONTINUEABLE_WATCHPOINT,
+       HAVE_STEPPABLE_WATCHPOINT, STOPPED_BY_WATCHPOINT,
+       target_insert_watchpoint, target_remove_watchpoint):
+       Move defines to ...
+       * config/i386/nm-i386sco5.h: ... here.
+       (kernel_u_size): Add prototype.  Improve a few comments and add
+       protection against multiple inclusion.
+       
+       * config/i386/nm-i386sco.h (FLOAT_INFO): Remove already commented
+       out define.
+
+       * uw-thread.c (SP_ARG0): Define if not already defined.
+       * config/i386/tm-i386.h (SO_ARG0): Remove define.
+
+       * config/i386/tm-i386v4.h (HAVE_I387_REGS): Remove define.
+
+       * config/i386/tm-i386.h: Don't include "regcache.h".
+
+       * i387-tdep.h (i387_print_float_info): New prototype.
+       * i387-tdep.c (print_i387_value, print_i387_ext,
+       print_i387_status_word, print_i387_control_word): Add `struct
+       ui_file *' argument and use it for output.
+       (i387_print_float_info): Renamed from i387_float_info.  Add
+       `struct gdbarch *' and `struct ui_file *' arguments and use the
+       latter for output.
+       * i386-tdep.c: Include "i387-tdep.h".
+       (i386_gdbarch_init): Set print_float_info.
+       * config/i386/tm-i386.h (i387_float_info): Remove prototype.
+       (FLOAT_INFO): Remove define.
+
+2002-08-13  Michael Snyder  <msnyder@redhat.com>
+
+       * mips-tdep.c (mips_push_arguments): Rename to
+       mips_eabi_push_arguments, and tune for EABI.
+       (MIPS_REGS_HAVE_HOME_P): Delete.
+       (struct gdbarch_tdep): Remove mips_regs_have_home_p field.
+       (mips_gdbarch_init): Set gdbarch push_arguments for eabi.
+       Delete references to mips_regs_have_home_p.
+
+2002-08-14  Keith Seitz  <keiths@redhat.com>
+
+       * Makefile.in (install-gdbtk): Create insight plugin directory.
+       Install plugins.tcl file.
+
+2002-08-14  Keith Seitz  <keiths@redhat.com>
+
+       * configure.in: Move SUBDIRS to near top of the file so that
+       --enable options may add things to it.
+       If gdbtk is enabled, add gdbtk directory to SUBDIRS and configdirs.
+       * configure: Regenerate.
+
+2002-08-13  Michael Snyder  <msnyder@redhat.com>
+
+       * mips-tdep.c (mips_o32o64_push_arguments):  New function, 
+       cloned from mips_push_arguments, tuned for o32/o64 ABI.
+       (mips_gdbarch_init): Set gdbarch_push_arguments to new func.
+
+2002-08-13  Andrew Cagney  <ac131313@redhat.com>
+
+       * vax-tdep.c (vax_get_saved_register): Delete function.
+       (vax_gdbarch_init): Update.
+       * ns32k-tdep.c (ns32k_get_saved_register): Delete function.
+       (ns32k_gdbarch_init): Update.
+       * alpha-tdep.c (alpha_get_saved_register): Delete function.
+       (alpha_gdbarch_init): Update.
+
+2002-08-13  Andrew Cagney  <cagney@redhat.com>
+
+       * regcache.c (init_regcache_descr): Overallocate the
+       raw_register_valid_p array including space for NUM_PSEUDO_REGS.
+       (registers_changed): Replace NUM_REGS+NUM_PSEUDO_REGS with
+       nr_raw_registers.
+       (set_register_cached): Add range checking assertions.  Use
+       current_regcache.
+
+2002-08-13  Mark Kettenis  <kettenis@gnu.org>
+
+       * i386-tdep.c (i386_stab_reg_to_regnum): Return correct register
+       numbers for MMX registers.
+
+2002-08-13  Andrew Cagney  <cagney@redhat.com>
+
+       * i386-tdep.c (i386_gdbarch_init): Use
+       generic_unwind_get_saved_register.
+
+2002-08-13  Kevin Buettner  <kevinb@redhat.com>
+
+       * procfs.c (procfs_can_use_hw_breakpoint): New function.
+       (init_procfs_ops): Define ``to_can_use_hw_breakpoint'' for procfs
+       target vector.
+       * config/mips/nm-irix5.h (TARGET_CAN_USE_HARDWARE_WATCHPOINT):
+       Delete.  Add comment regarding this now-deleted target method.
+
+2002-08-13  Stephane Carrez  <stcarrez@nerim.fr>
+
+       * m68hc11-tdep.c (M68HC12_NUM_PSEUDO_REGS): New define.
+       (M68HC12_HARD_PC_REGNUM): Define specific PC for 68HC12 (pseudo reg).
+       (m68hc11_pseudo_register_read): Compute the 68HC12 PC using the
+       real PC and the page number (if it's within the memory bank window).
+       (m68hc11_pseudo_register_write): Likewise when saving.
+       (m68hc11_register_name): Name the virtual pc 'pc' and the real one ppc.
+       (m68hc11_register_virtual_type): Return uint32 for virtual pc.
+       (m68hc11_register_raw_size): And use 32-bit for it.
+       (m68hc11_gdbarch_init): Use 32-bit address for 68HC12 if the
+       16K memory bank is used by the prog; also use the virtual pc.
+
+2002-08-13  Stephane Carrez  <stcarrez@nerim.fr>
+
+       * m68hc11-tdep.c (m68hc11_elf_make_msymbol_special): New function.
+       (m68hc11_gdbarch_init): Install it in gdbarch.
+       (MSYMBOL_SET_RTC, MSYMBOL_SET_RTI): New to set symbol specific flags.
+       (MSYMBOL_IS_RTC, MSYMBOL_IS_RTI): New to test these flags.
+       (MSYMBOL_SIZE): New for documentation.
+       (insn_return_kind): Enum to specify how a function returns.
+       (frame_extra_info): Cleanup and record the return mode.
+       (gdbarch_tdep, USE_PAGE_REGISTER): New to control the use of page 
+       register in address computation.
+       (m68hc11_get_return_insn): New to obtain the return instruction used
+       by the function.
+       (m68hc11_frame_init_saved_regs): Take into account the return
+       instruction used by the function for far and interrupt functions.
+       (m68hc11_init_extra_frame_info): Take into account page register.
+       (m68hc11_frame_args_address): Adjust according to the return mode.
+       (show_regs): Print page register only when it's used.
+
+2002-08-13  Stephane Carrez  <stcarrez@nerim.fr>
+
+       * m68hc11-tdep.c (HARD_PAGE_REGNUM): Define for 68HC12 page register.
+       (M68HC11_LAST_HARD_REG, m68hc11_register_names): Update.
+       (m68hc11_register_virtual_type): Return a 8-bit type for 8-bit
+       registers.
+       (m68hc11_register_raw_size): Likewise.
+
+2002-08-13  Andrew Cagney  <cagney@redhat.com>
+
+       * i386-tdep.c (i386_register_name): Handle mmx registers.
+       (mmx_regnum_p): New function.
+       (i386_mmx_names): New array.
+       (mmx_num_regs): New variable.
+       (i386_pseudo_register_read): New function.
+       (i386_pseudo_register_write): New function.
+       (mmx_regnum_to_fp_regnum): New function. Code from Fernando Nasser.
+
+       * regcache.c (regcache_raw_read_unsigned): New function.
+       (regcache_raw_read_signed): New function.
+       * regcache.h (regcache_raw_read_unsigned): Declare.
+       (regcache_raw_read_signed): Declare.
+
+2002-08-13  Andrew Cagney  <cagney@redhat.com>
+
+       * regcache.c (regcache_raw_read_as_address): Delete function.
+       (regcache_cooked_read_signed): New function.
+       (regcache_cooked_read_unsigned): New function.
+       * regcache.h (regcache_cooked_read_signed): Declare.
+       (regcache_cooked_read_unsigned): Declare.
+       (regcache_raw_read_as_address): Delete declaration.
+
+       * blockframe.c (generic_read_register_dummy): Use
+       regcache_cooked_read_unsigned.
+       * i386-tdep.c (i386_extract_struct_value_address): Use
+       regcache_cooked_read_unsigned.
+
+2002-08-13  Stephane Carrez  <stcarrez@nerim.fr>
+
+       * m68hc11-tdep.c (m68hc11_gdbarch_init): Set int, double and long
+       double sizes according to ELF ABI flags.
+       (gdbarch_tdep): Record elf_flags.
+
+2002-08-13  Stephane Carrez  <stcarrez@nerim.fr>
+
+       * m68hc11-tdep.c (M6812_OP_PSHX, M6812_OP_PSHY): New defines.
+       (m6812_prolog): They can appear in 68HC12 function prologue.
+       (m68hc11_frame_chain): Cleanup.
+
+2002-08-12  Andrew Cagney  <cagney@redhat.com>
+
+       * i386-tdep.h (i386_register_byte, i386_register_raw_size): Delete
+       declarations.
+       * i386-linux-tdep.c (i386_linux_register_byte): Delete function.
+       (i386_linux_register_raw_size): Delete function.
+       (i386_linux_init_abi): Update.
+       * i386-tdep.c (i386_register_raw_size): Delete function.
+       (i386_register_byte): Delete function.
+       (i386_gdbarch_init): Update.
+       (i386_register_size): Delete array.
+       (i386_register_offset): Delete array.
+
+       * config/i386/tm-symmetry.h (REGISTER_BYTE): Delete macro.
+       (REGISTER_RAW_SIZE): Delete macro.
+       * config/i386/tm-ptx.h (REGISTER_RAW_SIZE): Delete macro.
+       (REGISTER_BYTE): Delete macro.
+
+2002-08-11  Aidan Skinner <aidan@velvet.net>
+
+       * ada-lang.c (ada_lookup_partial_symbol)
+       (to_fixed_variant_branch_type) (find_line_in_linetable): Fix
+       prototype names so that grep ^func works properly.
+
+       * ada-lang.c (ada_array_element_type)
+       (ada_lookup_partial_symbol): Fix typos in parameter list.
+
+       * ada-valprint.c (val_print_packed_array_elements) (ada_val_print_1):
+       Fix prototype names so that grep ^func works properly.
+       
+2002-08-10  Andrew Cagney  <cagney@redhat.com>
+           Elena Zannoni  <ezannoni@redhat.com>
+           Martin M. Hunt  <hunt@redhat.com>
+
+       * gdbtypes.c (build_builtin_type_vec128): Set the vector bit.
+       (build_builtin_type_vec128i): Set the vector bit.
+       * gdbtypes.h (builtin_type_vec64, builtin_type_vec64i): Declare.
+       * gdbtypes.c (builtin_type_vec64, builtin_type_vec64i): Define.
+       (build_builtin_type_vec64): New function.
+       (build_builtin_type_vec64i): New function.
+       (build_gdbtypes): Initialize builtin_type_vec64 and
+       builtin_type_vec64i.
+
+2002-08-09  Andrew Cagney  <cagney@redhat.com>
+
+       * regcache.c (regcache_dump): Compare the register offset
+       with REGISTER_BYTE.
+       * arch-utils.c (generic_register_byte): New function.
+       * arch-utils.h (generic_register_byte): Declare.
+       * gdbarch.sh (REGISTER_BYTE): Default to generic_register_byte.
+       * gdbarch.h, gdbarch.c: Regenerate.
+
+2002-08-09  Andrew Cagney  <cagney@redhat.com>
+
+       * regcache.c: Include "gdbcmd.h"
+       (_initialize_regcache): Add commands "maintenance print
+       registers", "maintenance print raw-registers" and "maintenance
+       print cooked-registers".
+       (enum regcache_dump_what): Define.
+       (dump_endian_bytes): New function.
+       (regcache_dump): New function.
+       (regcache_print): New function.
+       (maintenance_print_registers): New function.
+       (maintenance_print_raw_registers): New function.
+       (maintenance_print_cooked_registers): New function.
+       * Makefile.in (regcache.o): Update dependencies.
+
+2002-08-09  Michael Snyder  <msnyder@redhat.com>
+
+       * mips-tdep.c (ROUND_DOWN, ROUND_UP): Move to global scope.
+       (mips_push_arguments): Correct some comments.  Use paddr_nz
+       for printing addresses in debug output.  Replace static
+       allocation using MAX_REGISTER_RAW_SIZE with alloca.
+       (mips_n32n64_push_arguments): New function, cloned from
+       mips_push_arguments and tuned for the n32/n64 ABI.
+       (mips_push_register): Buffer needs dynamic allocation.
+       (mips_print_register): Ditto.
+       (do_gp_register_row): Ditto.
+       (mips_store_return_value): Ditto.
+       (mips_gdbarch_init): Set gdbarch_push_arguments per ABI.
+
+2002-08-09  Don Howard  <dhoward@redhat.com>
+
+       * memattr.c (mem_info_command): Print special case of upper bound
+       as max CORE_ADDR + 1.
+
+2002-08-08  Michael Snyder  <msnyder@redhat.com>
+
+       * mips-tdep.c (mips_n32n64_use_struct_convention): N32 only 
+       returns structs by ref if they're too big to fit in two registers.
+
+2002-08-09  Kevin Buettner  <kevinb@redhat.com>
+
+       * mips-tdep.c (mips_init_extra_frame_info): Initialize SP_REGNUM's
+       saved regs value.
+       (read_next_frame_reg): Call FRAME_INIT_SAVED_REGS instead of
+       mips_find_saved_regs().
+       (mips_pop_frame): Likewise.
+
+2002-08-09  Kevin Buettner  <kevinb@redhat.com>
+
+       * blockframe.c (frame_saved_regs_register_unwind): Revise
+       PC_IN_CALL_DUMMY assertion to only apply when generic dummy
+       frames are in use.
+
+2002-08-09  Grace Sainsbury  <graces@redhat.com>
+        
+       * remote.c: (remote_wait, remote_async_wait): Add check for awatch
+        T-packets; the 'a' is not taken as a register number.
+       (remote_check_watch_resources, remote_stopped_by_watchpoint)
+        (remote_stopped_data_address): New functions; add to target
+        vector.
+        (remote_insert_hw_breakpoint, remote_remove_hw_breakpoint): Change
+        prototypes to match other implementations of this
+        function. replace integer argument with pointer -- the length
+        field in the Z-packet is the length of what is pointed to or 1 if
+        pointer is null. Add to target vector.
+        (remote_insert_watchpoint, remote_remove_watchpoint): Add to
+        target vector.
+
+        From Mark Salter:
+        * remote.c (remote_wait): Add support to extract optional
+        watchpoint information from T-packet. Ignore unrecognized
+        optional info in T-packet.
+        (remote_async_wait): Ditto.
+
+2002-08-09  Corinna Vinschen  <vinschen@redhat.com>
+
+       * cli/cli-dump.c: Change fopen modes to use binary open modes
+       as defined in include/fopen-bin.h throughout.
+
+2002-08-08  Michael Snyder  <msnyder@redhat.com>
+
+       * mips-tdep.c: Minor whitespace and indentation clean-ups.
+
+2002-08-08  Kevin Buettner  <kevinb@redhat.com>
+
+       * doublest.c (store_floating): Avoid floatformat_from_doublest()
+       assertion failure by returning early after a warning.
+
+2002-08-08  Kevin Buettner  <kevinb@redhat.com>
+
+       * mips-tdep.c (mips_find_saved_regs): Make static.
+       (mips_frame_init_saved_regs): New function.
+       (mips_gdbarch_init): Setup FRAME_INIT_SAVED_REGS method.
+       * config/mips/tm-mips.h (FRAME_INIT_SAVED_REGS): Delete macro.
+       (mips_find_saved_regs): Delete declaration.
+
+2002-08-08  Grace Sainsbury  <graces@redhat.com>
+
+       * remote.c (remote_wait, remote_async_wait): Change
+        thread_num from int to ULONGEST.
+       (unpack_varlen_hex): Change result parameter from
+       int * to ULONGEST *.
+
+2002-08-08  Andrew Cagney  <ac131313@redhat.com>
+
+       * configure.tgt: Replace powerpc-*-sysv*, powerpc-*-elf*,
+       powerpcle-*-eabi*, powerpcle-*-sysv* and powerpcle-*-elf* with
+       powerpc*-*-*.
+       * MAINTAINERS: Remove redundant rs6000-ibm-aix4.1 target.
+
+2002-08-08  Andrew Cagney  <cagney@redhat.com>
+
+       * gcore.c (override_derive_stack_segment): Delete variable.
+       (preempt_derive_stack_segment): Delete function.
+       (derive_stack_segment): Delete function.
+       (default_derive_stack_segment): Renamed to derive_stack_segment.
+       (override_derive_heap_segment): Delete variable.
+       (preempt_derive_heap_segment): Delete function.
+       (derive_heap_segment): Delete function.
+       (default_derive_heap_segment): Rename to derive_heap_segment.
+
+2002-08-06  Michael Snyder  <msnyder@redhat.com>
+
+       * config/mips/tm-mips.h: Remove #define USE_STRUCT_CONVENTION.
+       * mips-tdep.c (mips_EABI_use_struct_convention, 
+       mips_OABI_use_struct_convention, mips_NABI_use_struct_convention):
+       New functions.  (mips_use_struct_convention): Delete.
+       (mips_gdbarch_init): set use_gdbarch_convention.
+
+2002-08-06  Michael Snyder  <msnyder@redhat.com>
+
+       *  mips-tdep.c: gdbarch-ify reg_struct_has_addr.
+       (mips_eabi_reg_struct_has_addr, mips_n32n64_reg_struct_has_addr, 
+       mips_o32_reg_struct_has_addr): New functions.
+       (mips_gdbarch_init): Set gdbarch reg_struct_has_addr.
+
+2002-08-07  Andrew Cagney  <ac131313@redhat.com>
+
+       * regcache.c (pseudo_register): Delete function.
+       (fetch_register): Delete function.
+       (store_register): Delete function.
+       (regcache_raw_read, legacy_read_register_gen): Use
+       target_fetch_registers instead of fetch_register.
+       (legacy_write_register_gen, regcache_raw_write): Use
+       target_store_register instead of store_register.
+       (write_register_bytes): Ditto.
+
+       * gdbarch.sh (FETCH_PSEUDO_REGISTER): Delete.
+       (STORE_PSEUDO_REGISTER): Delete.
+       * gdbarch.h, gdbarch.c: Regenerate.
+
+2002-08-06  Corinna Vinschen  <vinschen@redhat.com>
+
+       * cli/cli-dump.c (add_dump_command): Explicitely use "b" flag to
+       write dump file binary.
+
+2002-08-05  Michael Snyder  <msnyder@redhat.com>
+
+       *  mips-tdep.c (mips_find_saved_regs): Adjust stack according
+       to MIPS_SAVED_REGSIZE, not GDB_TARGET_IS_MIPS64.  Enhance comment.
+       (mips_gdbarch_init): Set N32 target to be mips64.
+
+2002-08-06  Kevin Buettner  <kevinb@redhat.com>
+
+       * frame.c (find_saved_register): Break out of loop once saved
+       register address is found.  Don't mention sparc in loop comment
+       anymore.
+
+2002-08-06  Kevin Buettner  <kevinb@redhat.com>
+
+       * mips-tdep.c (mips_gdbarch_init): For the N32 ABI, set
+       mips_default_saved_regsize to 8.
+
+2002-08-06  Andrew Cagney  <ac131313@redhat.com>
+
+       * gcore.c: Do not include <sys/procfs.h>.
+       * Makefile.in (gcore.o): Update dependencies.
+
+2002-08-06  Andrew Cagney  <cagney@redhat.com>
+
+       * configure.tgt: Make arc-*-* obsolete.
+       * NEWS: Mention that arc-*-* has been identifed as obsolete.
+       * MAINTAINERS: Make arc-elf obsolete.
+       * arc-tdep.c: Make file obsolete.
+       * config/arc/arc.mt: Ditto.
+       * config/arc/tm-arc.h: Ditto.
+
+2002-08-05  Theodore A. Roth  <troth@verinet.com>
+
+       * avr-tdep.c (avr_skip_prologue): Fix to return the correct pc.
+
+2002-08-05  Andrew Cagney  <ac131313@redhat.com>
+
+       * mcore-tdep.c (mcore_gdbarch_init): Use
+       generic_unwind_get_saved_register instead of
+       generic_get_saved_register.
+       * v850-tdep.c (v850_gdbarch_init): Ditto.
+       * frv-tdep.c (frv_gdbarch_init): Ditto.
+       * mn10300-tdep.c (mn10300_gdbarch_init): Ditto.
+       * s390-tdep.c (s390_gdbarch_init): Ditto.
+       * d10v-tdep.c (d10v_gdbarch_init): Ditto.
+       * config/mn10200/tm-mn10200.h (GET_SAVED_REGISTER): Ditto.
+       * config/h8300/tm-h8300.h (GET_SAVED_REGISTER): Ditto.
+
+2002-08-05  Joel Brobecker  <brobecker@gnat.com>
+
+       * objfiles.h: Add missing #include "symfile.h"
+
+       * Makefile.in (objfiles_h): Add dependency on symfile.h and dependents.
+
+2002-08-04  Andrew Cagney  <ac131313@redhat.com>
+
+       From 2002-08-01 david carlton <carlton@math.stanford.edu>:
+       * hpread.c (hpread_read_struct_type): Deleted superfluous setting
+       of FIELD_BITSIZE.
+
+2002-08-04  Daniel Jacobowitz  <drow@mvista.com>
+
+       * NEWS: Cleanup and nitpick.
+
+2002-08-03  Andrew Cagney  <ac131313@redhat.com>
+
+       * NEWS: Cleanup.  Use *-linux*-gnu*.  Only use `*' for headings.
+
+2002-08-03  Andrew Cagney  <ac131313@redhat.com>
+
+       * Makefile.in (gdbtk-bp.o): Update dependencies.
+       (gdbtk-register.o): Ditto.
+       (gdbtk-varobj.o): Ditto.
+
+2002-08-03  Andrew Cagney  <cagney@redhat.com>
+
+       * m68hc11-tdep.c (m68hc11_pseudo_register_read): Replace
+       m68hc11_fetch_pseudo_register.
+       (m68hc11_pseudo_register_write): Replace
+       m68hc11_store_pseudo_register.
+       (m68hc11_gdbarch_init): Update.
+
+Fri Aug  2 15:53:50 2002  Andrew Cagney  <cagney@redhat.com>
+
+       * gdbarch.sh: Include "gdb_string.h".
+       * gdbarch.c: Regenerate.
+
+       * regcache.c: Include "gdb_string.h".
+       * ax-general.c: Ditto.
+       * varobj.c: Ditto.
+       * std-regs.c: Ditto.
+       * fbsd-proc.c: Ditto.
+       * thread.c: Ditto.
+
+       * Makefile.in (regcache.o): Update dependencies.
+       (thread.o, gdbarch.o): Ditto.
+       (ax-general.o, gdbarch.o): Ditto.
+       (varobj.o, std-regs.o): Ditto.
+       (fbsd-proc.o): Specify dependencies.
+
+2002-08-02  Andrew Cagney  <cagney@redhat.com>
+
+       * regcache.c (regcache_cooked_read): Rename rawnum parameter to
+       regnum.
+       (regcache_cooked_write): Ditto.
+
+2002-08-02  Andrew Cagney  <ac131313@redhat.com>
+
+       * regcache.c (regcache_cooked_read): New function.
+       (regcache_cooked_write): New function.
+       (read_register_gen): Rewrite using regcache_cooked_read.
+       (write_register_gen): Rewrite using regcache_cooked_write.
+
+       * regcache.h (regcache_cooked_read, regcache_cooked_write):
+       Declare.
+
+2002-08-02  Andrew Cagney  <cagney@redhat.com>
+
+       * gdbarch.sh (pseudo_register_read, pseudo_register_write):
+       Replace the architecture methods register_read and register_write.
+       * gdbarch.h, gdbarch.c: Regenerate.
+       * regcache.c (init_regcache_descr): Update.
+       (read_register_gen): Update.
+       (write_register_gen): Update.
+       (supply_register): Update comment.
+
+       * sh-tdep.c (sh_gdbarch_init): Update.
+       (sh_pseudo_register_read, sh64_pseudo_register_read): Add
+       `regcache' and `gdbarch' parameters.  Make `buffer' a void
+       pointer.  Update code.
+       (sh_pseudo_register_write, sh64_pseudo_register_write): Add
+       `regcache' and `gdbarch' parameters.  Make `buffer' a constant
+       void pointer.  Update code.
+       (sh64_register_write): Delete.
+       (sh4_register_read): Delete.
+       (sh64_register_read): Delete.
+       (sh4_register_write): Delete.
+       (sh_sh4_register_convert_to_raw): Make `from' parameter a constant
+       void pointer, `to' parameter a void pointer.
+       (sh_sh64_register_convert_to_raw): Ditto.
+
+2002-08-01  Kevin Buettner  <kevinb@redhat.com>
+
+       * mips-tdep.c (mips_register_virtual_type): Use architecture
+       invariant return values.
+
+2002-08-01  Andrew Cagney  <cagney@redhat.com>
+
+       * linux-proc.c: Include "gdb_string.h".
+       * Makefile.in (linux-proc.o): Update dependency list.
+
+2002-08-01  Kevin Buettner  <kevinb@redhat.com>
+
+       * mips-tdep.c (mips_gdbarch_init): Add comments.  Fix typo in
+       comment.
+
+2002-08-01  Grace Sainsbury  <graces@redhat.com>
+
+       * target.h: Add to_insert_hw_breakpoint, to_remove_hw_breakpoint,
+       to_insert_watchpoint, to_remove_watchpoint,
+       to_stopped_by_watchpoint, to_stopped_data_address,
+       to_region_size_ok_for_hw_watchpoint, to_can_use_hw_breakpoint to
+       target vecctor. Define their corresponding macros so they call
+       them.
+       
+       * target.c: Add default and debug versions of for
+       to_insert_hw_breakpoint, to_remove_hw_breakpoint,
+       to_insert_watchpoint, to_remove_watchpoint,
+       to_stopped_by_watchpoint, to_stopped_data_address,
+       to_region_size_ok_for_hw_watchpoint, to_can_use_hw_breakpoint.
+
+2002-08-01  Kevin Buettner  <kevinb@redhat.com>
+
+       * mips-tdep.c (mips_register_virtual_type): New function.
+       (mips_gdbarch_init): Register mips_register_virtual_type()
+       with gdbarch machinery.
+       * config/mips/tm-irix6.h (mips/tm-bigmips64.h): Include
+       this file instead of tm-bigmips.h.
+       (MIPS_REGSIZE): Delete this macro.
+       (REGISTER_VIRTUAL_TYPE): Delete macro.  Undef macro so that
+       multiarch version in mips-tdep.c will be found.
+
+2002-08-01  Andrew Cagney  <cagney@redhat.com>
+
+       * NEWS: Menion that CHILL has been made obsolete.
+
+       * gdbtypes.c (chill_varying_type): Make chill references obsolete.
+       * stabsread.c (read_range_type): Ditto.
+       * gdbtypes.h: Ditto.
+       * language.c (binop_type_check): Ditto.
+       (binop_result_type): Ditto.
+       (integral_type): Ditto.
+       (character_type): Ditto.
+       (string_type): Ditto.
+       (boolean_type): Ditto.
+       (structured_type): Ditto.
+       (lang_bool_type): Ditto.
+       (binop_type_check): Ditto.
+       * language.h (_LANG_chill): Ditto.
+       * dwarfread.c (set_cu_language): Ditto.
+       * dwarfread.c (CHILL_PRODUCER): Ditto.
+       * dwarfread.c (handle_producer): Ditto.
+       * expression.h (enum exp_opcode): Ditto.
+       * eval.c: Ditto for comments.
+       * typeprint.c (typedef_print) [_LANG_chill]: Ditto.
+       * expprint.c (print_subexp): Ditto.
+       (print_subexp): Ditto.
+       * valops.c (value_cast): Ditto.
+       (search_struct_field): Ditto.
+       * value.h (COERCE_VARYING_ARRAY): Ditto.
+       * symfile.c (init_filename_language_table): Ditto.
+       (add_psymbol_with_dem_name_to_list): Ditto.
+       * valarith.c (value_binop): Ditto.
+       (value_neg): Ditto.
+       * valops.c (value_slice): Ditto.
+       * symtab.h (union language_specific): Ditto.
+       (SYMBOL_INIT_LANGUAGE_SPECIFIC): Ditto.
+       (SYMBOL_DEMANGLED_NAME): Ditto.
+       (SYMBOL_CHILL_DEMANGLED_NAME): Ditto.
+       * defs.h (enum language): Ditto.
+       * symtab.c (got_symtab): Ditto.
+       * utils.c (fprintf_symbol_filtered): Ditto.
+
+       * ch-typeprint.c: Make file obsolete.
+       * ch-valprint.c: Make file obsolete.
+       * ch-lang.h: Make file obsolete.
+       * ch-exp.c: Make file obsolete.
+       * ch-lang.c: Make file obsolete.
+
+       * Makefile.in (FLAGS_TO_PASS): Do not pass CHILL or CHILLFLAGS or
+       CHILL_LIB.
+       (TARGET_FLAGS_TO_PASS): Ditto.
+       (CHILLFLAGS): Obsolete.
+       (CHILL): Obsolete.
+       (CHILL_FOR_TARGET): Obsolete.
+       (CHILL_LIB): Obsolete.
+       (SFILES): Remove ch-exp.c, ch-lang.c, ch-typeprint.c and
+       ch-valprint.c.
+       (HFILES_NO_SRCDIR): Remove ch-lang.h.
+       (COMMON_OBS): Remove ch-valprint.o, ch-typeprint.o, ch-exp.o and
+       ch-lang.o.
+       (ch-exp.o, ch-lang.o, ch-typeprint.o, ch-valprint.o): Delete
+       targets.
+
+2002-07-31  Joel Brobecker  <brobecker@gnat.com>
+
+       * dwarf2read.c (set_cu_language): Add handler for LANG_Ada95.
+       This does not change anything at the moment, but will be helpful
+       later when full Ada support is integrated.
+
+2002-07-31  Kevin Buettner  <kevinb@redhat.com>
+
+       * mips-tdep.c (_initialize_mips_tdep): Add "n64" to "set mips abi"
+       help message.
+
+2002-07-31  Kevin Buettner  <kevinb@redhat.com>
+
+       * mips-tdep.c (mips_push_arguments): Fetch gdbarch_tdep struct
+       and save it in a local variable.  Use variable in later test.
+
+2002-07-31  Kevin Buettner  <kevinb@redhat.com>
+
+       * mips-tdep.c (mips_find_abi_section): Add N64 ABI recognition
+       test.  (Thanks to Daniel Jacobowitz.)
+       
+2002-07-31  Kevin Buettner  <kevinb@redhat.com>
+
+       * mips-tdep.c (enum mips_abi): Add MIPS_ABI_N64.
+       (mips_abi_strings): Add "n64".
+       (mips_gdbarch_init): Add test for n64 abi.  Add MIPS_ABI_N64 case.
+
+2002-07-31  Kevin Buettner  <kevinb@redhat.com>
+
+       * config/mips/tm-irix6.h (MIPS_REGSIZE): Define to be 8.
+       (REGISTER_VIRTUAL_TYPE): Some registers are now 64 bits wide.
+
+2002-07-31  Kevin Buettner  <kevinb@redhat.com>
+
+       * utils.c (host_pointer_to_address, address_to_host_pointer):
+       Use gdb_assert() instead of explicit call to internal_error().
+
+2002-07-30  Kevin Buettner  <kevinb@redhat.com>
+
+       * Makefile.in (rs6000-nat.o): Update dependencies.
+
+       From Nicholas Duffek:
+       * Makefile.in (ALLDEPFILES): Add aix-thread.c.
+       (aix-thread.o): New rule.
+       * configure.host (gdb_host): Set to aix432 on AIX 4.3.2+.
+       * config/powerpc/aix432.mh: New file.
+
+2002-07-30  Daniel Jacobowitz  <drow@mvista.com>
+
+       * ppc-linux-tdep.c (ELF_NGREG, ELF_NFPREG, ELF_NVRREG)
+       (ELF_FPREGSET_SIZE, ELF_GREGSET_SIZE): New enums.
+       (fetch_core_registers, ppc_linux_supply_gregset)
+       (ppc_linux_supply_fpregset): New functions.
+       (ppc_linux_regset_core_fns): New.
+       (_initialize_ppc_linux_tdep): Call add_core_fns.
+       * ppc-tdep.h: Add prototypes for ppc_linux_supply_fpregset
+       and ppc_linux_supply_gregset.
+       * ppc-linux-nat.c (supply_gregset): Call ppc_linux_supply_gregset.
+       (supply_fpregset): Call ppc_linux_supply_fpregset.
+       * config/powerpc/linux.mh (NATDEPFILES): Remove core-regset.o and
+       corelow.o.
+       * config/powerpc/linux.mt (TDEPFILES): Add corelow.o.
+
+2002-07-30  Daniel Jacobowitz  <drow@mvista.com>
+
+       * symtab.c (lookup_symbol): Demangle before lowercasing.
+
+2002-07-30  Andrew Cagney  <ac131313@redhat.com>
+
+       * symtab.h: Replace #include "gdb_obstack.h" with opaque
+       declaration.
+       * cli/cli-cmds.c, cli/cli-script.c: Include "gdb_string.h".
+       * gnu-v3-abi.c, arc-tdep.c, cli/cli-decode.c: Ditto.
+       * avr-tdep.c, mon960-rom.c, i960-tdep.c: Ditto.
+       * arch-utils.c, cli/cli-setshow.c: Unconditionally include
+       "gdb_string.h".
+       * Makefile.in (cli-script.o, cli-cmds.o): Update dependencies.
+       (gnu-v3-abi.o, cli-setshow.o, i960-tdep.o): Ditto.
+       (cli-decode.o, mi-cmd-var.o, mi-cmd-disas.o): Ditto.
+       (avr-tdep.o, mon960-rom.o): Ditto.
+       (aout_stabs_gnu_h): Define.
+       (symtab_h): Remove $(gdb_obstack_h).
+
+2002-07-30  Jim Blandy  <jimb@redhat.com>
+
+       Patch from David Carlton <carlton@math.stanford.edu>:
+       * gdbinit.in: Move the `dir' commands that add GDB's own source
+       directory to the search path to the end, so that the `gdb' source
+       directory will be searched first.
+
+2002-07-29  Andrew Cagney  <ac131313@redhat.com>
+
+       * gdb_obstack.h: New file.
+       * symtab.h: Include "gdb_obstack.h" instead of "obstack.h".
+       (obstack_chunk_alloc, obstack_chunk_free): Delete macros.
+       * objfiles.h: Include "gdb_obstack.h".
+       * Makefile.in (gdb_obstack_h): Define.
+       (symtab_h): Add $(gdb_obstack_h).
+       (objfiles_h): Add $(gdb_obstack_h).
+       
+       * objfiles.c: Include "gdb_obstack.h" instead of "obstack.h".
+       * macrotab.c, cp-valprint.c, dbxread.c: Ditto.
+       * ch-typeprint.c, ch-valprint.c, dstread.c: Ditto.
+       * macroexp.c, p-typeprint.c, stabsread.c: Ditto.
+       * symtab.c, f-typeprint.c, mdebugread.c: Ditto.
+       * p-valprint.c, symmisc.c, typeprint.c: Ditto.
+       * symfile.c, coffread.c, c-typeprint.c: Ditto.
+       * buildsym.c, bcache.c, ada-typeprint.c: Ditto.
+
+       * Makefile.in (bcache.o): Update dependencies.
+       (buildsym.o, c-typeprint.o, ch-typeprint.o): Ditto.
+       (ch-valprint.o, coffread.o, cp-valprint.o): Ditto.
+       (dbxread.o, dstread.o, f-typeprint.o): Ditto.
+       (objfiles.o, p-typeprint.o, p-valprint.o): Ditto.
+       (stabsread.o, symfile.o, symmisc.o): Ditto.
+       (symtab.o, typeprint.o, macroexp.o): Ditto.
+       (macrotab.o, mdebugread.o): Ditto.
+       (f_lang_h, coff_sym_h, coff_symconst_h): Define.
+       (coff_ecoff_h, aout_aout64_h): Define.
+       (aout_stabs_gnu_h, libaout_h): Define.
+
+2002-07-29  Andrew Cagney  <cagney@redhat.com>
+
+       * regcache.c (struct regcache_descr): Rename nr_registers to
+       nr_cooked_registers.  Revise comments describing the structure
+       member fields.
+       (init_regcache_descr): Update.
+       (init_legacy_regcache_descr): Update.
+       (read_register_gen, write_register_gen): When a cooked register in
+       the raw register range, directly access the value from the raw
+       register cache.
+
+2002-07-29  Andrew Cagney  <ac131313@redhat.com>
+
+       * z8k-tdep.c: Do not include "obstack.h".
+       * h8300-tdep.c, h8500-tdep.c: Ditto.
+       * m68hc11-tdep.c, sh-tdep.c: Ditto.
+       * valprint.c, v850-tdep.c: Ditto.
+       * d10v-tdep.c, mn10300-tdep.c: Ditto.
+       * mn10200-tdep.c: Ditto.
+
+       * Makefile.in (z8k-tdep.o): Update dependencies.
+       (m68hc11-tdep.o, valprint.o): Ditto.
+       (v850-tdep.o, d10v-tdep.o): Ditto.
+       (mn10300-tdep.o, sparc-tdep.o): Ditto.
+       (sh-tdep.o, h8500-tdep.o, h8300-tdep.o): Ditto.
+       (m32r-tdep.o, mn10200-tdep.o): Specify dependencies.
+       (sh_opc_h, gdb_sim_sh_h): Define.
+       (elf_sh_h, elf_bfd_h): Define.
+       (opcode_m68hc11_h): Define.
+       (OPCODES_SRC, OPCODES_DIR): define.
+       (OPCODES): Use $(OPCODES_DIR).
+       (gdb_sim_d10v_h): Rename sim_d10v_h.
+       (gdb_sim_arm_h): Rename sim_arm_h.
+
+2002-07-26  Kevin Buettner  <kevinb@redhat.com>
+
+       * utils.c (host_pointer_to_address, address_to_host_pointer):
+       Change internal_error() message to indicate function responsible
+       for the error.
+
+2002-07-26  Kevin Buettner  <kevinb@redhat.com>
+
+       * ui-out.c (ui_out_field_core_addr): Remove unnecessary cast in
+       calls to local_hex_string_custom().
+
+2002-07-26  Kevin Buettner  <kevinb@redhat.com>
+
+       * irix5-nat.c: Move IRIX shared library support from here...
+       * solib-irix.c: ...to here.  Revised substantially to work with
+       generic solib framework.
+
+       * osabi.h (gdb_osabi): Add new enum constant GDB_OSABI_IRIX.
+       * osabi.c (gdb_osabi_names): Add corresponding string for Irix.
+       * mips-irix-tdep.c: New file.
+
+       * Makefile.in (ALLDEPFILES): Add mips-irix-tdep.c and solib-irix.c.
+       (mips-irix-tdep.o, solib-irix.o): New rules.
+       * config/mips/irix5.mt (TDEPFILES): Add mips-irix-tdep.o, solib.o,
+       solib-irix.o.
+       * config/mips/irix6.mt (TDEPFILES): Likewise.
+       * config/mips/irix6.mh (NATDEPFILES): Remove solib.o.
+
+2002-07-26  Kevin Buettner  <kevinb@redhat.com>
+
+       * aix-thread.c (coff/internal.h, bfd/libcoff.h, pthread.h): Remove
+       disabled (via ``#if 0'') includes.
+
+2002-07-26  Kevin Buettner  <kevinb@redhat.com>
+
+       * aix-thread.c (special_register_p, supply_sprs64, supply_sprs32)
+       (fetch_regs_user_thread, fetch_regs_kernel_thread, fill_sprs64)
+       (fill_sprs32, store_regs_user_thread, store_regs_kernel_thread):
+       Add support for the fpscr register.
+       * rs6000-nat.c (regmap, fetch_inferior_registers)
+       (store_inferior_registers, fetch_core_registers): Likewise.
+
+2002-07-26  Kevin Buettner  <kevinb@redhat.com>
+
+       * rs6000-nat.c (language.h): Include.
+       (special_regs): Delete this array.
+       (regmap): New function.
+       (fetch_register, store_register):  Use regmap() to map gdb
+       register numbers to ptrace register numbers.  Also, use
+       outputs from regmap() to make decisions regarding type of
+       ptrace() call to make.  In particular, don't compare against
+       FIRST_UISA_SP_REGNUM or LAST_UISA_SP_REGNUM.
+       (fetch_inferior_registers, store_inferior_registers): Where
+       possible, obtain register numbers from tdep struct.  Don't
+       refer to FIRST_UISA_SP_REGNUM or LAST_UISA_SP_REGNUM.
+       * config/rs6000/tm-rs6000.h (FIRST_UISA_SP_REGNUM)
+       (LAST_UISA_SP_REGNUM): Delete.
+       
+2002-07-25  Kevin Buettner  <kevinb@redhat.com>
+
+       * rs6000-nat.c (ppc-tdep.h): Include.
+       (fetch_registers, store_register, fetch_core_registers): Don't
+       access registers[] directly.  Instead, use supply_register() or
+       regcache_collect() as appropriate.
+       (find_toc_address): Format hex address with local_hex_string().
+
+2002-07-25  Andrew Cagney  <ac131313@redhat.com>
+
+       * config/djgpp/fnchange.lst: Rename bfd/elf32-fr30.c and
+       bfd/elf32-frv.c.
+
+2002-07-24  Tom Tromey  <tromey@redhat.com>
+
+       * jv-exp.y: Marked all strings with _().
+       (ClassInstanceCreationExpression, ArrayCreationExpression): Use
+       internal_error.
+       (MethodInvocation, CastExpression, parse_number, yyerror,
+       java_type_from_name, push_expression_name, yylex): Typo fixes.
+
+2002-07-24  Daniel Jacobowitz  <drow@mvista.com>
+
+       * ui-file.c (struct tee_file, tee_file_new, tee_file_delete)
+       (tee_file_flush, tee_file_write, tee_file_fputs)
+       (tee_file_isatty): New.
+       * ui-file.h (tee_file_new): Add prototype.
+
+2002-07-24  Aidan Skinner <aidan@velvet.net>
+
+       * ada-lang.c: Change k&r style function definitions to prototyped
+       form.
+       * ada-typeprint.c: Change k&r style function definitions to prototyped
+       form.
+       * ada-valprint.c: Change k&r style function definitions to prototyped
+       form.
+       
+2002-07-24  Andrew Cagney  <cagney@redhat.com>
+
+       * README: Remove reference to remote-bug.
+       * Makefile.in (ALLDEPFILES): Remove m88k-nat.c, m88k-tdep.c and
+       remote-bug.c.
+       (m88k-nat.o): Delete rule.
+       (m88k-tdep.o): Delete rule.
+       (remote-bug.o): Delete rule.
+       * MAINTAINERS: Mark as obsolete.
+       * elfread.c (elf_symtab_read): Mention that m88k is obsolete.
+       * m88k-tdep.c: Make file obsolete.
+       * config/m88k/m88k.mh: Ditto.
+       * config/m88k/delta88v4.mh: Ditto.
+       * config/m88k/delta88v4.mt: Ditto.
+       * config/m88k/delta88.mt: Ditto.
+       * config/m88k/delta88.mh: Ditto.
+       * remote-bug.c: Ditto.
+       * config/m88k/tm-delta88.h: Ditto.
+       * config/m88k/nm-delta88v4.h: Ditto.
+       * config/m88k/xm-delta88.h: Ditto.
+       * config/m88k/xm-dgux.h: Ditto.
+       * config/m88k/tm-m88k.h: Ditto.
+       * config/m88k/nm-m88k.h: Ditto.
+       * config/m88k/tm-delta88v4.h: Ditto.
+       * m88k-nat.c: Ditto.
+       * cxux-nat.c: Ditto.
+       * configure.host: Make m88*-motorola-sysv4*, m88*-motorola-sysv*
+       and m88*-*-* obsolete.
+       * configure.tgt: Make m88*-motorola-sysv4*, m88*-motorola-* and
+       m88*-*-* obsolete.
+
+2002-07-24  Andrew Cagney  <cagney@redhat.com>
+
+       * findvar.c (extract_unsigned_integer): Make `addr' parameter
+       constant.  Same for local pointer variables.
+       (extract_signed_integer): Ditto.
+       * defs.h (extract_unsigned_integer): Update.
+       (extract_signed_integer): Update.
+
+2002-07-24  Andrew Cagney  <cagney@redhat.com>
+
+       * regcache.c (regcache_raw_write): Change buf parameter to a
+       constant void pointer.
+       (regcache_raw_read): Change buf parameter to a void pointer.
+       (legacy_write_register_gen): Change myaddr parameter a constant
+       void pointer.
+       (supply_register): Change val parameter to a const void pointer.
+       * regcache.h (regcache_raw_write): Update declaration.
+       (regcache_raw_read): Update declaration.
+       (supply_register): Update declaration.
+
+2002-07-24  Tom Tromey  <tromey@redhat.com>
+
+       * defs.h (gdb_readline_wrapper): Declare.
+       * utils.c (prompt_for_continue): Use gdb_readline_wrapper.
+       * tracepoint.c (read_actions): Use gdb_readline_wrapper.
+       * top.c (gdb_readline_wrapper): New function.
+       (command_line_input): Use it.
+
+2002-07-24  Andrew Cagney  <cagney@redhat.com>
+
+       * regcache.h (regcache_raw_read, regcache_raw_write): Replace
+       regcache_read and regcache_write.
+       (regcache_raw_read_as_address): Replace regcache_read_as_address.
+       * regcache.c: Update.
+       * sh-tdep.c (sh64_push_arguments): Update comment.
+       (sh_pseudo_register_read): Update.
+       (sh_pseudo_register_write): Update.
+       (sh4_register_read): Update.
+       (sh4_register_write): Update.
+       (sh64_pseudo_register_read): Update.
+       (sh64_pseudo_register_write): Update.
+       (sh64_register_read): Update.
+       (sh64_register_write): Update.
+       * i386-tdep.c (i386_extract_return_value): Update.
+       (i386_extract_struct_value_address): Update.
+       (i386_extract_return_value): Update.
+       * blockframe.c (generic_read_register_dummy): Update.
+       (generic_call_dummy_register_unwind): Update
+       * infrun.c (write_inferior_status_register): Update.
+
+2002-07-23  Jim Blandy  <jimb@redhat.com>
+
+       * parser-defs.h (expression_context_pc): Make this extern.
+       (Thanks to Michael Snyder.)
+
+2002-07-23  Andrew Cagney  <ac131313@redhat.com>
+
+       GDB 5.2.1 released from 5.2 branch.
+       * NEWS: Mention changes in 5.2.1 including addition of AVR target.
+       * README: Update to mention 5.2.1.
+
+2002-07-23  Mark Salter  <msalter@redhat.com>
+
+       * remote.c (remote_read_bytes): Fix check for error.
+
+2002-07-22  Kevin Buettner  <kevinb@redhat.com>
+
+       * aix-thread.c (language.h): Include.
+       (ptrace_check, pdc_symbol_addrs, pdc_read_regs, pdc_write_regs)
+       (pdc_read_data, pdc_write_data, pdc_alloc, pdc_realloc, pdc_dealloc):
+       Print newlines at end of debug messages.
+       (pdc_symbol_addrs, pdc_read_regs, pdc_write_regs, pdc_read_data)
+       (pdc_write_data): Use local_hex_string() instead of %llx formats.
+
+2002-07-22  Kevin Buettner  <kevinb@redhat.com>
+
+       * aix-thread.c (ppc-tdep.h): Include.
+       (special_register_p): New function.
+       (supply_sprs64, supply_sprs32, fill_sprs64, fill_sprs32)
+       (store_regs_user_thread): Use register number information from
+       gdbarch_tdep struct instead of hardcoded offsets relative to
+       FIRST_UISA_SP_REGNUM.
+       (fetch_regs_kernel_thread, store_regs_kernel_thread):  Call
+       special_register_p() instead of using FPLAST_REGNUM and
+       LAST_UISA_SP_REGNUM as lower and upper bounds on the special
+       register numbers.  Also, don't assume that LAST_UISA_SP_REGNUM
+       will be MQ's register number.
+
+2002-07-22  Michael Snyder  <msnyder@redhat.com>
+
+       * aix-thread.c (ops): Rename to aix_thread_ops.
+       (base_ops): Rename to base_target.
+       (ops_attach): Rename to aix_thread_attach.
+       (ops_detach): Rename to aix_thread_detach.
+       (ops_resume): Rename to aix_thread_detach.
+       (ops_wait):   Rename to aix_thread_wait.
+       (ops_kill):   Rename to aix_thread_kill.
+       (init_ops):   Rename to init_aix_thread_ops.
+       (ops_fetch_register): Rename to aix_thread_fetch_register.
+       (ops_store_register): Rename to aix_thread_store_register.
+       (ops_mourn_inferior): Rename to aix_thread_mourn_inferior.
+       (ops_thread_alive):   Rename to aix_thread_thread_alive.
+       (ops_extra_thread_info: Rename to aix_thread_extra_thread_info.
+       (ops_pid_to_str):  Rename to aix_thread_pid_to_str.
+       (ops_xfer_memory): Rename to aix_thread_xfer_memory.
+       (fetch_regs_lib):  Rename to fetch_regs_user_thread.
+       (fetch_regs_kern): Rename to fetch_regs_kernel_thread.
+       (store_regs_lib):  Rename to store_regs_user_thread.
+       (store_regs_kern): Rename to store_regs_kernel_thread.
+
+2002-07-22  Michael Snyder  <msnyder@redhat.com>
+
+       * aix-thread.c (ops_prepare_to_store): Eliminate.
+       (init_ops): Don't initialize ops.prepare_to_store.
+       (store_regs_kern): Pre-fetch register buffers from child, 
+       because some registers may not be in the cache.  Copy
+       regs from register cache only if they are cached.
+       (store_regs_lib): Copy regs from register cache only
+       if they are cached.
+       (fill_sprs32, (fill_sprs64, fill_fprs, fill_gprs32,
+       fill_gprs64): Ditto.
+
+2002-07-22  Kevin Buettner  <kevinb@redhat.com>
+
+       * aix-thread.c (gdb_assert.h): Include.
+       (fill_sprs64, fill_sprs32): Add selected asserts to make sure that
+       register sizes (from register cache) match size of buffer holding
+       register data.
+       (fill_sprs32): Change parameter types to match those in the ptrace()
+       buffer.
+       (store_regs_lib): Likewise, but for 32-bit temporary variables.
+       (ops_prepare_to_store): Rename loop variable ``i'' to ``regno''.
+
+2002-07-22  Michael Snyder  <msnyder@redhat.com>
+
+       * aix-thread.c (supply_sprs64): Cosmetic change.
+       (supply_sprs32): Cosmetic change.
+       (fill_gprs64, fill_gprs32, fill_fprs, fill_sprs32): New funcs.
+       (fill_sprs64): Use regcache_collect instead of read_register.
+       (store_regs_lib): Use regcache_collect instead of 
+       read_register.  Use fill_sprs32 instead of fill_sprs64,
+       if debugging a 32-bit architecture.
+       (store_regs_kern): Use fill_gprs64 etc. to pull the values
+       out of the register cache, instead of passing a pointer into
+       the register cache directly to ptrace.  Use regcache_collect
+       insteaad of read_register.
+       (ops_prepare_to_store): Use target_read_registers instead
+       of read_register_bytes.
+
+2002-07-20  Aidan Skinner <aidan@velvet.net>
+
+       * MAINTAINERS: Add self under write after approval. 
+               
+2002-07-20  Aidan Skinner <aidan@velvet.net>
+
+       * ada-tasks.c: Change k&r style function definitions to prototyped
+       form.
+               
+2002-07-19  Andrew Cagney  <ac131313@redhat.com>
+
+       * Makefile.in (x86-64-tdep.o): Add $(objfiles_h).
+       * x86-64-tdep.c: Include "objfiles.h".
+       (x86_64_gdbarch_init): Set in_solib_call_trampoline to
+       in_plt_section.  From 2002-07-18 Michal Ludvig <mludvig@suse.cz>.
+
+2002-07-17  Michal Ludvig  <michal@suse.cz>
+
+       * dwarf2cfi.c (execute_stack_op): Complain on unknown DW_OP_ value.
+       (update_context): Initialise cfa variable.
+
+2002-07-17  Michael Snyder  <msnyder@redhat.com>
+
+       * aix-thread.c: Shorten some long lines.  
+       Bring comments into line with code spec.
+
+2002-07-18  Joel Brobecker  <brobecker@gnat.com>
+
+       * infrun.c: Re-indent using gdb_indent.sh.
+
+2002-07-18  Joel Brobecker  <brobecker@gnat.com>
+
+       * infrun.c (handle_inferior_event): Remove unneeded extra brace.
+       Leave the indentation temporarily untouched, to minimize the diffs.
+
+2002-07-18  Elena Zannoni  <ezannoni@redhat.com>
+
+       * stabsread.c: Make os9k sections of the code obsolete,
+       for real this time.
+       * stabsread.h: Make os9k sections of the code obsolete.
+
+2002-07-18  Michal Ludvig <mludvig@suse.cz>
+
+       * linux-low.c (regsets_store_inferior_registers): Add free()
+       at the end of a loop to prevent memory leak.
+       * linux-x86-64-low.c (x86_64_regmap): Add CS, SS registers.
+       (X86_64_NUM_GREGS): Count it from the size of x86_64_regmap.
+       * config/sparc/tm-sp64linux.h: Make the rest of #endif
+       line a comment.
+       * Makefile.in (x86-64-linux-nat.o): Remove dependency on i387-tdep.h
+
+2002-07-17  Jim Blandy  <jimb@redhat.com>
+
+       * macrocmd.c (info_macro_command): Remove newline from error
+       message.
+
+2002-07-17  J"orn Rennecke <joern.rennecke@superh.com>
+
+       * sh-tdep.c (sh_dsp_register_sim_regno): New function.
+       (sh_gdbarch_init): Use it for sh-dsp.
+
+2002-07-16  Kevin Buettner  <kevinb@redhat.com>
+
+       * dwarf2read.c (read_initial_length): Handle older, non-standard,
+       64-bit DWARF2 format.
+
+2002-07-16  Joel Brobecker  <brobecker@gnat.com>
+
+       * proc-api.c: use HAVE_SYS_PROC_H macro to avoid including
+       <sys/proc.h> when not available.
+
+2002-07-16  Andrew Cagney  <ac131313@redhat.com>
+
+       * NEWS: Mention that the i[34]86-*-os9k has been made obsolete.
+       * stabsread.c: Make os9k sections of the code obsolete.
+       * configure.tgt: Make i[3456]86-*-os9k target obsolete.
+       * config/i386/i386os9k.mt: Make file obsolete.
+       * Makefile.in (ALLDEPFILES): Remove remote-os9k.c.
+       (COMMON_OBS): Remove os9kread.o
+       (SFILES): Remove os9kread.c.
+       (os9kread.o, remote-os9k.o): Make target obsolete.
+       * remote-os9k.c: Make file obsolete.
+       * os9kread.c: Make file obsolete.
+       * Makefile.in
+
+2002-07-16  Andrew Cagney  <ac131313@redhat.com>
+
+       * NEWS: Mention that the FR30 has been made obsolete.
+       * fr30-tdep.c: Make file obsolete.
+       * config/fr30/tm-fr30.h: Ditto.
+       * config/fr30/fr30.mt: Ditto.
+       * configure.tgt: Make fr30-*-elf obsolete.
+       * MAINTAINERS: Make fr30-elf obsolete.
+
+2002-07-16  Pierre Muller  <muller@ics.u-strasbg.fr>
+
+       * blockframe.c (get_pc_function_start): return 0 if the minimal symbol
+       found is not inside a section.
+
+2002-07-15  Kevin Buettner  <kevinb@redhat.com>
+
+       * aix-thread.c (ptrace_check): Use safe_strerror() instead of
+       strerror().
+       (pdc_realloc): Use xrealloc() instead of realloc().
+
+2002-07-15  Kevin Buettner  <kevinb@redhat.com>
+
+       * aix-thread.c (PD_ERROR, CALL_BASE): Delete.
+       (ops_resume, ops_wait, fetch_regs_lib, store_regs_lib)
+       (ops_xfer_memory, ops_kill): Don't use PD_ERROR or CALL_BASE
+       macros.
+
+2002-07-15  Kevin Buettner  <kevinb@redhat.com>
+
+       * aix-thread.c (ptrace_check): Eliminate goto.
+       (sync_threadlists): Eliminate gotos.  Also, fix array overrun
+       problem.
+
+2002-07-15  Kevin Buettner  <kevinb@redhat.com>
+
+       * aix-thread.c (gdbcmd.h): Include.
+       (DEBUG, DBG, DBG2, dbg): Eliminate.
+       (debug_aix_thread): New static global.
+       (ptrace_check, pdc_symbol_addrs, pdc_read_regs, pdc_write_regs)
+       (pdc_read_data, pdc_write_data, pdc_alloc, pdc_realloc, pdc_dealloc)
+       (fetch_regs_lib, store_regs_lib, store_regs_kern): Rewrite
+       invocations to DBG and DBG2 macros to test against
+       ``debug_aix_thread'' and call fprintf_unfiltered().
+       (_initialize_aix_thread): Add new command "set debug aix-thread".
+
+2002-07-15  Andrew Cagney  <ac131313@redhat.com>
+
+       From Gerhard Tonn <TON@de.ibm.com>:
+       * s390-nat.c (fill_fpregset, fill_gregset): Use regcache_collect
+       instead of supply_register.
+
+2002-07-15  Andrew Cagney  <ac131313@redhat.com>
+
+       * dwarf2cfi.c: Include "gdb_assert.h".
+       (frame_state_for): Use gdb_assert to check that fde->cie_ptr is
+       non-NULL.
+       (update_context): Do not use __func__.  Add missing ``break''.
+       (update_context): Do not use __func__.
+
+2002-07-15  Elena Zannoni  <ezannoni@redhat.com>
+
+        * rs6000-tdep.c (rs6000_gdbarch_init): Remove variable print_insn
+        and its setting.  Set gdbarch instruction printing functions
+        directly.  For non-rs6000 case use new function
+        gdb_print_insn_powerpc.
+        (gdb_print_insn_powerpc): New function.
+
+2002-07-13  Andrew Cagney  <ac131313@redhat.com>
+
+       * NEWS: Mention that the d30v has been marked obsolete.
+       * MAINTAINERS: Note that d30v / d30v-elf has been made obsolete.
+       * configure.tgt: Mark d30v-*-* as obsolete.
+       * d30v-tdep.c: Mark file as obsolete.
+       * config/d30v/d30v.mt: Ditto.
+       * config/d30v/tm-d30v.h: Ditto.
+
+2002-07-13  Aidan Skinner <aidan@velvet.net>
+
+       * ada-tasks.c (add_task_entry): replace calls to
+       malloc() with xmalloc
+       * ada-tasks.c (init_task_list): replace calls to free with xfree()
+       
+       * ada-lang.c (replace_operator_with_call, fill_in_ada_prototype,
+       ada_finish_decode_line_1, all_sals_for_line
+       ada_breakpoint_rewrite): replace calls to free() with xfree()
+               
+2002-07-12  Kevin Buettner  <kevinb@redhat.com>
+
+       From Nicholas Duffek (with minor changes by Martin Hunt, 
+       Louis Hamilton, and Kevin Buettner):
+       * aix-thread.c: New file.
+
+2002-07-12  Petr Sorfa <petrs@caldera.com>
+
+        *  dwarf2read.c (dwarf2_invalid_attrib_class): New
+        complaint for invalid attribute class or form.
+        (read_func_scope): DW_AT_frame_base
+        better handling of DW_AT_block*.
+        (dwarf2_add_member_fn): DW_AT_vtable_elem_location
+        better handling of DW_AT_block*.
+        (read_common_block): DW_AT_location
+        better handling of DW_AT_block*.
+        (read_partial_die): DW_AT_location better handling
+        of DW_AT_block*.
+        (new_symbol): DW_AT_external better handling of
+        DW_AT_block*. Proper initialization of variable
+        "addr".
+        (attr_form_is_block): New function that returns true
+        if the attribute's form is of DW_FORM_block*.
+
+2002-07-12  Peter Schauer  <Peter.Schauer@Regent.E-Technik.TU-Muenchen.DE>
+
+       * valops.c (find_method_list): Remove comment about
+       removed STATIC_MEMFUNCP argument.
+       (value_find_oload_method_list): Likewise.
+
+2002-07-12  Kevin Buettner  <kevinb@redhat.com>
+
+       From Nicholas Duffek:
+       * rs6000-nat.c (vmap_ldinfo, xcoff_relocate_core): Call
+       target_new_objfile_hook.
+
+2002-07-12  Kevin Buettner  <kevinb@redhat.com>
+
+       From Nicholas Duffek:
+       * xcoffread.c (scan_xcoff_symtab): Recognize XMC_TD as a data storage
+       csect.
+
+2002-07-12  Andrew Cagney  <cagney@redhat.com>
+
+       * MAINTAINERS: Mention --enable-sim-build-warnings.
+       (m68hc11-elf): Disable sim build warnings.
+       (m32r-elf): Mark as broken obsolete candidate.
+       (x86_64-linux-gnu): Mark as buildable with -Werror.
+       (arm-elf): Change -w to ``,'' which enables warnings but not
+       -Werror.
+
+2002-07-12  Andrew Cagney  <ac131313@redhat.com>
+
+       * bcache.h: Update copyright.
+       (struct bstring, struct bcache): Move definition to "bcache.c".
+       Replaced by opaque declaration.
+       (bcache_xfree): Replace free_bcache.
+       (bcache_xmalloc, bcache_memory_used): Declare.
+       
+       * bcache.c: Update copyright.
+       (struct bstring, struct bcache): Moved to here from "bcache.h".
+       Update comments.
+       (bcache_xmalloc, bcache_memory_used): New functions.
+       (bcache_xfree): Replace function free_bcache.
+       
+       * Makefile.in (objfiles.o): Add $(bcache_h).
+       (objfiles_h): Remove $(bcache_h).
+       (symfile.o): Add $(bcache_h).
+
+       * symmisc.c: Update copyright.
+       (print_symbol_bcache_statistics): Pass psymbol_cache by value.
+       (print_objfile_statistics): Use bcache_memory_used.
+
+       * symfile.c: Include "bcache.h".
+       (reread_symbols): Use bcache_xfree.
+       (reread_symbols): Use bcache_xmalloc and bcache_xfree.
+       (add_psymbol_to_list): Pass psymbol_cache by value.
+       (add_psymbol_with_dem_name_to_list): Ditto.
+
+       * objfiles.h: Update copyright.
+       (struct bcache): Declare opaque.  Do not include "bcache.h".
+       (struct objfile): Change psymbol_cache and macro_cache to ``struct
+       bcache'' pointers.
+       * dwarf2read.c (macro_start_file): Pass macro_cache by value.
+
+       * objfiles.c: Include "bcache.h".  Update copyright.
+       (allocate_objfile): Use bcache_xmalloc to create psymbol_cache and
+       macro_cache.
+       (free_objfile): Use bcache_xfree.
+
+2002-07-11  Grace Sainsbury  <graces@redhat.com>
+
+       * monitor.c (monitor_fetch_register): Make name a constant.
+       (monitor_store_register): Same.
+
+2002-07-11  Daniel Jacobowitz  <drow@mvista.com>
+
+       Based on patch from Daniel Berlin <dberlin@dberlin.org>.
+       * buildsym.c: Include "demangle.h" for SYMBOL_INIT_DEMANGLED_NAME.
+       (finish_block) For non-function blocks, hash the symbol table.  For
+       function blocks, mark the symbol table as unhashed.
+       * minsyms.c (msymbol_hash): Return hash value without taking modulus.
+       (msymbol_hash_iw): Likewise.
+       (add_minsym_to_hash_table): Take modulus of msymbol_hash's return
+       value.
+       (add_minsym_to_demangled_hash_table): Likewise for msymbol_hash_iw.
+       (lookup_minimal_symbol): Likewise for both.
+       * symtab.h (struct block): Add `hashtable' flag.  Comment the
+       hashtable.
+       (BLOCK_HASHTABLE, BLOCK_BUCKETS, BLOCK_BUCKET): New macro.
+       (ALL_BLOCK_SYMBOLS): Update.
+       (BLOCK_SHOULD_SORT): Do not sort hashed blocks.
+       (struct symbol): Add `hash_next' pointer.
+       * symtab.c (lookup_block_symbol): Search using the hash table when
+       possible.
+       (find_pc_sect_symtab): Use ALL_BLOCK_SYMBOLS.
+       (search_symbols, find_addr_symbol): Likewise.
+
+       * dstread.c (process_dst_block): Clear hashtable bit for new block.
+       (read_dst_symtab): Likewise.
+       * jv-lang.c (get_java_class_symtab): Likewise.
+       * mdebugread.c: Include "gdb_assert.h".
+       (shrink_block): Assert that the block being modified is not hashed.
+       * coffread.c (patch_opaque_types): Use ALL_BLOCK_SYMBOLS.
+       * symmisc.c (free_symtab_block): Walk the hash table when freeing
+       symbols.
+       (dump_symtab): Recognize hashed blocks.
+       * printcmd.c (print_frame_args):  Assert that function blocks do not
+       have hashed symbol tables.
+       * ada-lang.c (symtab_for_sym): Use ALL_BLOCK_SYMBOLS.
+       (fill_in_ada_prototype, debug_print_block): Likewise.
+       (ada_add_block_symbols): Use ALL_BLOCK_SYMBOLS.  Handle hash tables.
+
+2002-07-11  Corinna Vinschen  <vinschen@redhat.com>
+
+       * stack.c (print_frame): Use result of frame_address_in_block()
+       instead of fi->pc when evaluating symbols.
+       (backtrace_command_1): Ditto.
+
+2002-07-11  Andrew Cagney  <cagney@redhat.com>
+
+       * cris-tdep.c (cris_saved_pc_after_call): Fix parameter type.
+       Make static.
+
+       * arm-tdep.c (arm_register_name): Make return type constant.
+
+2002-07-10  Andrew Cagney  <ac131313@redhat.com>
+
+       * win32-nat.c (has_detach_ability): Convert to strict ISO C
+       prototype.
+       * top.c (gdb_rl_operate_and_get_next_completion): Ditto.
+       * s390-tdep.c (s390_fp_regnum): Ditto.
+       (s390_read_fp): Ditto.
+       (s390_pop_frame): Ditto.
+       (_initialize_s390_tdep): Ditto.
+       * remote.c (get_remote_state): Ditto.
+       * procfs.c (mappingflags): Ditto.
+       * memattr.c (_initialize_mem): Ditto.
+       * mcore-tdep.c (mcore_pop_frame): Ditto.
+       * m68klinux-nat.c (_initialize_m68k_linux_nat): Ditto.
+       * m68k-tdep.c (m68k_register_bytes_ok): Ditto.
+       * language.c (set_case_str): Ditto.
+       * gnu-v3-abi.c (vtable_address_point_offset): Ditto.
+       * frv-tdep.c (new_variant): Ditto.
+       (frv_stopped_data_address): Ditto.
+       * dwarf2cfi.c (fde_chunks_need_space): Ditto.
+       (context_alloc): Ditto.
+       (frame_state_alloc): Ditto.
+       (unwind_tmp_obstack_init): Ditto.
+       (unwind_tmp_obstack_free): Ditto.
+       (cfi_read_fp): Ditto.
+       * cris-tdep.c (cris_saved_pc_after_call): Ditto.
+       (cris_pop_frame): Ditto.
+       * c-lang.c (scanning_macro_expansion): Ditto.
+       (finished_macro_expansion): Ditto.
+       (c_preprocess_and_parse): Ditto.
+       * gdbarch.sh: Ditto.
+       * gdbarch.h, gdbarch.c: Regenerate.
+       * config/mn10200/tm-mn10200.h: Adjust indentation.
+       * target.c: Adjust indentation.
+       * symtab.h: Adjust indentation.
+       * stabsread.h: Adjust indentation.
+       * remote-es.c: Adjust indentation.
+       * os9kread.c: Adjust indentation.
+
+2002-07-10  Andrew Cagney  <ac131313@redhat.com>
+       
+       * wince.c (_initialize_wince): Rename _initialize_inftarg.
+       * win32-nat.c (_initialize_win32_nat): Rename _initialize_inftarg.
+
+2002-07-10  Grace Sainsbury  <graces@redhat.com>
+       
+       * NEWS: Mention m68k, mcore multi-arching.  
+       * MAINTAINERS: Change status of m68k, mcore to reflect
+       multi-arching.
+
+2002-07-10  Daniel Jacobowitz  <drow@mvista.com>
+
+       * valops.c (find_overload_match): Free oload_syms.
+
+2002-07-09  Joel Brobecker  <brobecker@gnat.com>
+
+       Define HAVE_SYS_PROC_H if sys/proc.h exists
+       * configure.in: Add check for sys/proc.h
+       * config.in: Regenerate.
+       * configure: Regenerate.
+
+2002-07-09  Grace Sainsbury  <graces@redhat.com>
+
+       * config/m68k/tm-m68k.h: Remove macros wrapped in 
+       #if !GDB_MULTI_ARCH. 
+
+2002-07-08  Andrew Cagney  <ac131313@redhat.com>
+
+       * config.in, configure: Regenerate.
+
+2002-07-08  Mark Kettenis  <kettenis@gnu.org>
+
+       * dwarf2cfi.c: Include "gcore.h".
+       (execute_stack_op): Fix implementation of the
+       DW_OP_deref and DW_OP_deref_size operators by letting do their
+       lookup in the target.
+
+2002-07-07  Mark Kettenis  <kettenis@gnu.org>
+
+       From Peter Schauer <Peter.Schauer@regent.e-technik.tu-muenchen.de>:
+       * i386-sol2-tdep.c (i386_sol2_init_abi): Correct value for
+       tdep->sc_sp_offset.
+
+2002-07-05  Daniel Jacobowitz  <drow@mvista.com>
+
+       Fix PR gdb/595, gdb/602
+       * gnu-v3-abi.c (gnuv3_baseclass_offset): Remove unused variables.
+       Don't call value_cast, just read the vtable pointer; update comments
+       to match.
+
+2002-07-05  Grace Sainsbury  <graces@redhat.com>
+
+       * config/mcore/tm-mcore.h: Remove file.
+       * config/mcore/mcore.mt: Remove definition of TM_FILE
+       * configure.tgt: Set gdb_multi_arch to yes for the mcore target.
+
+2002-07-05  Mark Kettenis  <kettenis@gnu.org>
+
+       * i386bsd-tdep.c: Include "gdb_string.h".
+
+2002-07-04  Grace Sainsbury  <graces@redhat.com>
+
+       * config/mcore/tm-mcore.h (GDB_MULTI_ARCH): Set to 2.
+       (PR_REGNUM, FIRST_ARGREG, LAST_ARGREG,RETVAL_REGNUM): Move to
+       mcore-tdep.
+       (REG_STRUCT_HAS_ADDR, USE_STRUCT_CONVENTION, GET_SAVED_REGISTER)
+       (TARGET_VIRTUAL_FRAME_POINTER, BELIEVE_PCC_PROMOTION): Remove.
+       * mcore-tdep.c (PR_REGNUM, FIRST_ARGREG, LAST_ARGREG)
+       (RETVAL_REGNUM): Move macros from tm-mcore.h
+       (mcore_reg_struct_has_addr): New function.
+       (mcore_gdbarch_init): Added initializations for the macros removed
+       from tm-mcore.h.
+
+2002-07-04  Mark Kettenis  <kettenis@gnu.org>
+
+       * osabi.c (generic_elf_osabi_sniffer): Add check for FreeBSD 3.x's
+       traditonal string branding within the ELF header.
+
+2002-07-04  Daniel Jacobowitz  <drow@mvista.com>
+
+       * symtab.c (remove_params): New function.
+       (make_symbol_overload_list): Use it instead of cplus_demangle.
+       (overload_list_add_symbol): Likewise.  Reorder.  Fix memory leak.
+
+2002-07-04  Mark Kettenis  <kettenis@gnu.org>
+
+       * i386obsd-nat.c (_initialize_i386obsd_nat): Fix typo in prototype.
+
+       * i386bsd-tdep.c (i386nbsd_sigtramp_start, i386nbsd_sigtramp_end):
+       New variables.
+       (i386nbsd_init_abi): Use these to initialize tdep->sigtramp_start
+       and tdep->sigtramp_end.
+       * i386obsd-nat.c: New file.
+       * config/i386/obsd.mh (NATDEPFILES): Add i386obsd-nat.o.
+
+       * dwarf2cfi.c (cfi_pop_frame): Use alloca() for regbuf.
+       Don't call get_current_frame().
+
+2002-07-04  Pierre Muller  <muller@ics.u-strasbg.fr>
+
+       * i386-nat.c (child_post_startup_inferior): New function
+       calling i386_cleanup_dregs if
+       I386_USE_GENERIC_WATCHPOINTS is defined.
+       * config/i386/nm-i386.h: define CHILD_POST_STARTUP_INFERIOR
+       conditional to acknowledge that i386-nat.c has its
+       own child_post_startup_inferior function.
+
+2002-07-04  Mark Kettenis  <kettenis@gnu.org>
+
+       * i386-tdep.h (I386_MAX_REGISTER_SIZE): New define.
+       * i386-tdep.c (i386_do_pop_frame): Use I386_MAX_REGISTER_SIZE
+       instead of MAX_REGISTER_RAW_SIZE.
+       (i386_extract_return_value, i386_extract_struct_value_address):
+       Convert to use regcache.
+       (i386_gdbarch_init): Set max_register_raw_size and
+       max_register_virtual_size to I386_MAX_REGISTER_SIZE.
+       Set extract_return_value and extract_struct_value_address instead
+       of their deprecated variants.
+
+       Convert i386 target to generic dummy frames.
+       * i386-tdep.c: Include "symfile.h".
+       (i386_frameless_signal_p): Consider a function to be frameless if
+       the pc points at the first instruction of the function.
+       (i386_frame_chain): Handle (generic) call dummies.
+       (i386_frame_saved_pc): Likewise.
+       (i386_frame_init_saved_regs): Remove code dealing with call
+       dummies on the stack.
+       (i386_push_dummy_frame): Removed.
+       (i386_call_dummy_words): Removed.
+       (i386_fix_call_dummy): Removed.
+       (i386_push_return_address): New function.
+       (i386_do_pop_frame): Renamed from i386_pop_frame.  Add FRAME
+       parameter, and don't call get_current_frame.
+       (i386_pop_frame): New function.
+       (i386_gdbarch_init): Set use_generic_dummy_frames to 1, set
+       call_dummy_location to AT_ENTRY_POINT, set call_dummy_address to
+       entry_point_address, set call_dummy_breakpoint_offset to 0, set
+       call_dummy_length to 0, set call_dummy_words to NULL, set
+       sizeof_call_dummy_words to 0, set fix_call_dummy to
+       generic_fix_call_dummy, set pc_in_call_dummy to
+       pc_in_call_dummy_at_entry_point, set push_dummy_frame to
+       generic_push_dummy_frame, set push_return_address to
+       i386_push_return_address and set frame_chain_valid to
+       generic_file_frame_chain_valid.
+
+2002-07-03  Andrew Cagney  <ac131313@redhat.com>
+
+       * gdbarch.sh (struct regcache): Add opaque declaration.
+       (EXTRACT_RETURN_VALUE): New architecture method.
+       (EXTRACT_STRUCT_VALUE_ADDRESS): Ditto.
+       * gdbarch.h, gdbarch.c: Regenerate.
+       * arch-utils.c (legacy_extract_return_value): New function.
+       * arch-utils.h (legacy_extract_return_value): Declare.
+       * values.c (value_being_returned): Re-enable code handling
+       EXTRACT_STRUCT_VALUE_ADDRESS.  Move
+       deprecated_grub_regcache_for_registers call to block handling
+       DEPRECATED_EXTRACT_STRUCT_VALUE_ADDRESS.
+       (EXTRACT_RETURN_VALUE): Do not define.
+
+2002-07-03  Grace Sainsbury  <graces@redhat.com>
+
+       * config/mcore/tm-mcore.h (REGISTER_BYTES, NUM_REGS, PC_REGNUM)
+       (SP_REGNUM, FP_REGNUM, FUNCTION_START_OFFSET, DECR_PC_AFTER_BREAK)
+       (BREAKPOINT_FROM_PC, INNER_THAN, SAVED_PC_AFTER_CALL)
+       (INIT_EXTRA_FRAME_INFO, FRAME_INIT_SAVED_REGS, INIT_FRAME_PC)
+       (FRAME_CHAIN, FRAME_CHAIN_VALID, FRAME_SAVED_PC)
+       (STORE_RETURN_VALUE, DEPRECATED_EXTRACT_RETURN_VALUE)
+       (STORE_STRUCT_RETURN, DEPRECATED_EXTRACT_STRUCT_VALUE_ADDRESS)
+       (SKIP_PROLOGUE, FRAME_ARGS_SKIP, FRAME_ARGS_ADDRESS)
+       (FRAME_LOCALS_ADDRESS, FRAME_NUM_ARGS, POP_FRAME)
+       (PUSH_RETURN_ADDRESS, PUSH_DUMMY_FRAME, PUSH_ARGUMENTS): Remove.
+       * mcore-tdep.c (mcore_init_extra_frame_info): Add fromleaf
+       argument so the function fits the prototype in the architecture
+       vector.
+       (mcore_pop_frame): Remove argument so the function fits the
+       prototype. Use get_current_frame instead of the argument.
+       (mcore_push_arguments): Change type of struct_return so the
+       function can be used in the architecture vector.
+       (mcore_store_struct_return): Add.
+       (mcore_frame_init_saved_regs): Add.
+       (mcore_gdbarch_init): Add function calls to replace the macros
+       removed from tm-mcore.h
+
+2002-07-03  Andrew Cagney  <ac131313@redhat.com>
+
+       * infcmd.c (print_return_value): Remove compatibility code calling
+       deprecated_grub_regcache_for_registers.
+       
+       * values.c: Include "regcache.h".
+       (value_being_returned): Update.  Use
+       deprecated_grub_regcache_for_registers to extract the register
+       buffer address.  
+       * value.h (value_being_returned): Change ``retbuf'' parameter to a
+       ``struct regcache''.
+       * Makefile.in (values.o): Add dependency on $(regcache_h).
+
+       * inferior.h (run_stack_dummy): Change type of second parameter to
+       a ``struct regcache''.
+       * valops.c (hand_function_call): Change type of retbuf to ``struct
+       regcache''.  Allocate using regcache_xmalloc, clean using
+       make_cleanup_regcache_xfree.
+       * infcmd.c (run_stack_dummy): Update.  Use
+       regcache_cpu_no_passthrough instead of memcpy to copy the buffer.
+
+       * regcache.c (do_regcache_xfree): New function.
+       (make_cleanup_regcache_xfree): New function.
+       * regcache.h (make_cleanup_regcache_xfree): Declare.
+
+2002-07-03  Martin M. Hunt  <hunt@redhat.com>
+
+       * event-top.c (command_line_handler): Don't read past
+        beginning of buffer.
+
+2002-07-03  Martin M. Hunt  <hunt@redhat.com>
+       
+        * varobj.c (struct varobj_root): Change frame from CORE_ADDR to 
+        struct frame_id. 
+        (varobj_create): Store frame_id for root.
+        (varobj_gen_name): Use xasprintf.
+        (varobj_update): Save and restore frame using get_frame_id() and
+        frame_find_by_id().
+        (create_child): Use xasprintf.
+        (new_root_variable): Initialize frame_id.
+        (c_name_of_child): Use xasprintf. Call find_frame_by_id().
+        (c_value_of_variable): Use xasprintf. Move mem_fileopen call
+        to prevent memory leak.
+
+2002-07-03  Andrew Cagney  <ac131313@redhat.com>
+
+       * valops.c (hand_function_call): Move declaration of retbuf to
+       start of function, allocate using malloc, add a cleanup but before
+       the inf_status cleanup, cleanup the buffer.  Rename local variable
+       old_chain to inf_status_cleanup.
+
+2002-07-03  Martin M. Hunt  <hunt@redhat.com>
+
+       * top.c (execute_command): Use cmd_func() and cmd_func_p().
+
+       * cli/cli-decode.c (cmd_func_p): New function.
+       (cmd_func): New function.
+
+       * command.h: Add cmd_func() and cmd_func_p().   
+       
+2002-07-03  Grace Sainsbury  <graces@redhat.com>
+
+       * config/mcore/tm-mcore.h (GDB_MULTI_ARCH): Add macro. Set to 0.
+       (REGISTER_SIZE): Remove.
+       (MAX_REGISTER_RAW_SIZE): Remove.
+       (REGISTER_VIRTUAL_TYPE): Remove.
+       (MAX_REGISTER_VIRTUAL_SIZE): Remove.
+       (REGISTER_NAME): Remove.
+       (USE_GENERIC_DUMMY_FRAMES): Remove.
+       (CALL_DUMMY): Remove.
+       (CALL_DUMMY_START_OFFSET): Remove.
+       (CALL_DUMMY_BREAKPOINT_OFFSET): Remove.
+       (CALL_DUMMY_LOCATION): Remove.
+       (FIX_CALL_DUMMY): Remove.
+       (CALL_DUMMY_ADDRESS): Remove.
+       (SIZEOF_CALL_DUMMY_WORDS): Remove.
+       (SAVE_DUMMY_FRAME_TOS): Remove.
+       * mcore-tdep.c (MCORE_REG_SIZE, MCORE_NUM_REGS): Add macros.
+       (mcore_register_virtual_type): New function.
+       (mcore_register_byte): New function.
+       (mcore_register_size): New function.
+       (mcore_register_name): New function.
+       (mcore_gdbarch_init): New function. Add set_gdbarch calls for
+       macros removed from tm-mcore.h.
+       (mcore_dump_tdep): Add.
+       (_initialize_mcore_tdep): Add gdbarch_register call.
+
+2002-07-03  Mark Kettenis  <kettenis@gnu.org>
+
+       * i386-tdep.c (i386_frameless_signal_p): Provide an argument in to
+       frameless_look_for_prologue, such that we actually call this
+       function.
+
+2002-07-02  Joel Brobecker  <brobecker@gnat.com>
+
+       * frame.h (frame_address_in_block): New function.
+
+       * blockframe.c (frame_address_in_block): New function extracted
+       from get_frame_block().
+       (get_frame_block): Use frame_address_in_block().
+       (block_innermost_frame): Use frame_address_in_block() to match
+       the frame pc address against the block boundaries rather than
+       the frame pc directly. This prevents a failure when a frame pc
+       is actually a return-address pointing immediately after the end
+       of the given block. 
+
+2002-07-02  Grace Sainsbury  <graces@redhat.com>
+
+       * MAINTAINERS: Add self under write after approval. 
+
+2002-07-02  Grace Sainsbury  <graces@redhat.com>
+
+       * m68k-tdep.c (m68k_remote_breakpoint_from_pc): Add. Currently not
+       used in architecture vector. The default is
+       m68k_local_breakpoint_from_pc.
+        (m68k_local_breakpoint_from_pc): Add.
+        (enum): Add register numbers from tm-m68k.h.
+        (m68k_gdbarch_init): Add breakpoint_from_pc to architecture
+       vector.  
+       * config/m68k/tm-m68k.h (GDB_MULTI_ARCH): Set to
+       GDB_MULTI_ARCH_PARTIAL.
+        (BPT_VECTOR, REGISTER_BYTES_FP, REGISTER_BYTES_NOFP)
+        (NUM_FREGS, SIG_PC_FP_OFFSET, SP_ARG0, REMOTE_BPT_VECTOR): Move to
+       m68k-tdep.c.
+        (BREAKPOINT, REMOTE_BREAKPOINT): Remove.
+        (A1_REGNUM, FP0_REGNUM, FPC_REGNUM, FPS_REGNUM, FPI_REGNUM): Move
+       to enum in m68k-tdep.c
+
+2002-07-02  Joel Brobecker  <brobecker@gnat.com>
+
+       * solib-osf.c (open_map): Compute the list of shared libraries
+       loaded by the inferior, rather than the list of libraries loaded
+       by GDB itself.  Otherwise, GDB ends up reading the symbols from
+       the wrong shared libraries...
+
+2002-07-02  Mark Kettenis  <kettenis@gnu.org>
+
+       * i386-linux-tdep.c (i386_linux_sigcontext_addr): Make static.
+       (LINUX_SIGCONTEXT_PC_OFFSET, LINUX_SIGCONEXT_SP_OFFSET): Remove
+       macros.
+       (i386_linux_sigtramp_saved_pc, i386_linux_sigtramp_saved_sp):
+       Remove functions.
+       (FRAMELESS_SIGNAL): Remove function.
+       (i386_linux_frame_chain, i386_linux_frame_saved_pc,
+       i386_linux_saved_pc_after_call): Removed.
+       (i386_linux_init_abi): Initialize tdep->sigcontext_addr,
+       tdep->sc_pc_offset and tdep->sc_sp_offset.  Don't override
+       frame_chain, frame_saved_pc and saved_pc_after_call any longer.
+
+       * i386-tdep.c (i386_frameless_signal_p): New function.
+       (i386_frame_chain): Deal with frameless signals.
+       (i386_sigtramp_saved_sp): New function.
+       (i386_frame_saved_pc): Deal with frameless signals.
+       (i386_saved_pc_after_call): Make sure the correct value is
+       returned just after entry into a sigtramp.
+       * i386bsd-tdep.c (i386bsd_sc_sp_offset, i386nbsd_sc_sp_offset,
+       i386fbsd4_sc_sp_offset): New variables.
+       (i386bsd_init_abi, i386nbsd_init_abi, i386fbsd4_init_abi): Use
+       these variables to initialize tdep->sc_sp_offset.  * i386bsd-nat.c
+       (_initialize_i386bsd_nat): Add sanity check for sc_sp_offset
+       similiar to what we already did for sc_pc_offset.
+       * i386-sol2-tdep.c (i386_sol2_init_abi): Initialize
+       tdep->sc_sp_offset.
+
+       * i386nbsd-tdep.c (fetch_elfcore_registers): Wrap long line.
+
+2002-07-02  Michal Ludvig  <mludvig@suse.cz>
+
+       * config/i386/tm-x86-64linux.h: New.
+       * config/i386/x86-64linux.mt: Add GDB_MULTI_ARCH and TM_FILE
+       definitions.
+       * config/i386/nm-x86-64.h: Rename to ...
+       * config/i386/nm-x86-64linux.h: ... this one.
+       * config/i386/x86-64linux.mh: Reflect the above change.
+       
+2002-07-01  Mark Kettenis  <kettenis@gnu.org>
+
+       * i386-tdep.h (struct gdbarch_tdep): Replace sigtramp_saved_pc
+       with sigcontext_addr.  Add sc_sp_offset.
+       (i386bsd_sigtramp_saved_pc): Remove prototype.
+       (i386bsd_sicontext_addr): Add prototype.
+       * i386-tdep.c (i386_sigtramp_saved_pc): New function.
+       (i386_frame_saved_pc): Rewrite to call i386_sigtramp_saved_pc.
+       (i386_svr4_sigtramp_saved_pc): Removed.
+       (i386_svr4_sigcontext_addr): New function.
+       (i386_svr4_init_abi): Don't initialize tdep->sigtramp_saved_pc.
+       Initialize tdep->sigcontext_addr instead.  Initialize
+       tdep->sc_pc_offset and tdep->sc_sp_offset.
+       (i386_gdbarch_init): Likewise.
+       * i386bsd-tdep.c (i386bsd_sigcontext_addr): Don't make it static
+       any more.
+       (i386bsd_sigtramp_saved_pc): Remove function.
+       (i386bsd_init_abi): Don't initialize tdep->sigtramp_saved_pc.
+       Initialize tdep->sigcontext_addr instead.  Initialize
+       tdep->sc_pc_offset.
+       * i386-linux-tdep.c (i386_linux_init_abi): Remove initialization
+       of tdep->sigtramp_saved_pc.
+       * i386-sol2-tdep.c (i386_sol2_init_abi): Don't initialize
+       tdep->sigtramp_saved_pc.  Initialize tdep->sigcontext_addr
+       instead.
+
+       * i386-tdep.c (i386_frameless_function_invocation,
+       i386_frame_num_args, i386_frame_init_saved_regs,
+       i386_skip_prologue, i386_push_dummy_frame, i386_fix_call_dummy,
+       i386_pop_frame, i386_push_arguments, i386_store_struct_return,
+       i386_extract_return_value, i386_store_return_value,
+       i386_extract_struct_value_address, i386_register_virtual_type,
+       i386_register_convertible, i386_register_convert_to_virtual,
+       i386_register_convert_to_raw, i386_svr4_sigtramp_saved_pc,
+       i386_go32_init_abi, i386_nw_init_abi, i386_gdbarch_init): Make
+       static.
+
+2002-07-01  Mark Kettenis  <kettenis@gnu.org>
+
+       * i386bsd-tdep.c (i386bsd_frame_saved_pc): Removed.
+
+       * config/i386/tm-i386sol2.h (COERCE_FLOAT_TO_DOUBLE): Removed.
+       * i386-sol2-tdep.c (i386_sol2_init_abi): Adjust for the removal of
+       this macro.  Include "value.h".
+
+2002-06-30  Aidan Skinner  <aidan@velvet.net>
+
+       * ada-exp.tab.c: remove as it's a generated file
+       * ada-lex.c: remove as it's a generated file
+               
+2002-06-30  Mark Kettenis  <kettenis@gnu.org>
+
+       * config/i386/tm-i386.h (struct frame_info, struct
+       frame_saved_regs, struct value, struct type): Remove forward
+       declarations.
+
+       * config/i386/tm-linux.h [HAVE_PTRACE_GETFPXREGS]
+       (FILL_FPXREGSET, HAVE_SSE_REGS): Remove define.
+       * config/i386/nm-linux.h [HAVE_PTRACE_GETFPXREGS]
+       (FILL_FPXREGSET): Define.
+
+       * config/i386/tm-nbsd.h (HAVE_SSE_REGS): Remove define.
+
+       * configure.tgt (i[3456]86-*-openbsd*): Fold into
+       i[3456]86-*-netbsd* case.
+       * config/i386/tm-obsd.h: Removed.
+       * config/i386/obsd.mt: Removed.
+       * config/i386/obsd.mh (NATDEPFILES): Remove corelow.o and
+       core-aout.o.
+       (MH_CFLAGS): Add -DYYDEBUG=0.
+
+       * i386bsd-nat.c (_initialize_i386bsd_nat): Define SC_PC_OFFSET to
+       i386nbsd_sc_pc_offset on OpenBSD too.
+
+       * config/i386/tm-fbsd.h [!SVR4_SHARED_LIBS]
+       (IN_SOLIB_CALL_TRAMPOLINE): Remove define.
+       * config/i386/tm-nbsdaout.h (IN_SOLIB_CALL_TRAMPOLINE): Remove
+       define.
+       * i386bsd-tdep.c: Include "arch-utils.h".
+       (i386bsd_aout_in_solib_call_trampoline): New function.
+       (i386bsd_init_abi): Set in_solib_call_trampoline to
+       i386bsd_aout_in_solib_call_trampoline.
+       (i386nbsdelf_init_abi, i386fbsd_init_abi): Set
+       in_solib_call_trampoline to generic_in_solib_call_trampoline.
+
+2002-06-28  Andrew Cagney  <ac131313@redhat.com>
+
+       * macrotab.h: Do not include "obstack.h" or "bcache.h".
+       (struct obstack, struct bcache): Add opaque declarations.
+       * Makefile.in (macrotab_h): Update
+
+2002-06-28  Andrew Cagney  <ac131313@redhat.com>
+
+       * blockframe.c (generic_find_dummy_frame): Change return type to
+       ``struct regcache''.
+       (struct dummy_frame): Replace field ``registers'' with regcache, a
+       struct regcache object.
+       (generic_find_dummy_frame): Update.
+       (generic_push_dummy_frame): Update.  Use regcache_xfree,
+       regcache_xmalloc and regcache_cpy.
+       (generic_pop_dummy_frame): Update.  Use regcache_cpy and
+       regcache_xfree.
+       (deprecated_generic_find_dummy_frame): Update.
+       (generic_read_register_dummy): Update.  Use
+       regcache_read_as_address.
+       (generic_call_dummy_register_unwind): Update.  Use regcache_read.
+       (generic_get_saved_register): Update.  Use regcache_read.
+
+2002-06-28  Andrew Cagney  <ac131313@redhat.com>
+
+       * Makefile.in (objfiles_h): Add $(bcache_h).
+       * objfiles.h: Include "bcache.h".
+
+       * Makefile.in (symtab_h): Remove $(bcache_h).
+       * symtab.h: Do not include "bcache.h".
+
+2002-06-28  Andrew Cagney  <ac131313@redhat.com>
+
+       * ppcnbsd-tdep.c (ppcnbsd_init_abi): Set frame_chain_valid to
+       generic_func_frame_chain_valid.
+
+2002-06-28  David O'Brien  <obrien@FreeBSD.org>
+
+       * config/i386/nm-fbsd.h: Include <sys/param.h>.
+       * config/i386/tm-fbsd.h: Likewise.
+
+2002-06-28  Andrew Cagney  <ac131313@redhat.com>
+
+       * rs6000-tdep.c (rs6000_gdbarch_init): Use
+       generic_unwind_get_saved_register.
+
+2002-06-27  Andrew Cagney  <ac131313@redhat.com>
+
+       From 2002-06-27 John David Anglin <dave@hiauly1.hia.nrc.ca>:
+       * regcache.c (supply_register): Add missing argument to
+       register_buffer call.
+
+2002-06-27  Andrew Cagney  <ac131313@redhat.com>
+
+       * Makefile.in (init.c): Drop -e option to grep.  Not necessary and
+       Solaris /bin/grep does not not like it.  From Peter Schauer.
+
+2002-06-26  Tom Tromey  <tromey@redhat.com>
+
+       * command.h (add_setshow_cmd): Declare.
+       (add_setshow_cmd_full): Declare.
+       * cli/cli-decode.c (add_setshow_cmd): No longer static.  Now
+       returns void.  Use add_setshow_cmd_full.
+       (add_setshow_cmd_full): New function.
+       (add_setshow_auto_boolean_cmd): Use add_setshow_cmd_full.
+       (add_setshow_boolean_cmd): Likewise.
+
+2002-06-26  Jason Thorpe  <thorpej@wasabisystems.com>
+
+       * config/vax/tm-vax.h: Protect from multiple inclusion.
+       (TARGET_UPAGES, TARGET_NBPG, STACK_END_ADDR)
+       (SIGTRAMP_START, SIGTRAMP_END, SIGCONTEXT_PC_OFFSET): Move to...
+       * config/vax/tm-vaxbsd.h: ...here.  New file.
+       * config/vax/vax.mt (TM_FILE): Set to tm-vaxbsd.h.
+
+2002-06-26  Jason Thorpe  <thorpej@wasabisystems.com>
+
+       * config/vax/tm-vax.h (BREAKPOINT): Remove.
+       (BELIEVE_PCC_PROMOTION): Remove.
+       (AP_REGNUM): Move to...
+       * config/vax/nm-vax.h: ...here.
+       * vax-tdep.c: Use VAX_AP_REGNUM instead of AP_REGNUM.
+       (vax_breakpoint_from_pc): New function.
+       (vax_gdbarch_init): Initialize gdbarch_breakpoint_from_pc
+       and gdbarch_believe_pcc_promotion.
+
+2002-06-26  Jason Thorpe  <thorpej@wasabisystems.com>
+
+       * Makefile.in (vax_tdep_h): Define.  
+       (vax-tdep.o): Use $(vax_tdep_h).
+       * vax-tdep.c (vax_gdbarch_init): Use generic OS ABI framework.
+       (vax_dump_tdep): New function. 
+       (_initialize_vax_tdep): Register vax_dump_tdep.
+       * vax-tdep.h: Include osabi.h.     
+       (struct gdbarch_tdep): New. 
+
+2002-06-26  Andrew Cagney  <cagney@redhat.com>
+
+       * frame.h (deprecated_generic_find_dummy_frame): Rename
+       generic_find_dummy_frame.
+       * blockframe.c (generic_find_dummy_frame): Make static.
+       (deprecated_generic_find_dummy_frame): New function.
+       * sh-tdep.c (sh_nofp_frame_init_saved_regs): Replace
+       generic_find_dummy_frame with deprecated_find_dummy_frame.
+       (sh64_nofp_frame_init_saved_regs): Ditto.
+       (sh_fp_frame_init_saved_regs): Ditto.
+       * s390-tdep.c (s390_frame_saved_pc_nofix): Ditto.
+       (s390_frame_chain): Ditto.
+       * cris-tdep.c (cris_frame_init_saved_regs): Ditto.
+
+2002-06-26  Grace Sainsbury  <graces@redhat.com>
+
+       * config/m68k/tm-m68k.h: Rearrange code so macros not in the
+       gdbarch vector are at the top.
+       (NUM_REGS): Remove.
+       (FP_REGNUM, SP_REGNUM, PS_REGNUM, PC_REGNUM, FP0_REGNUM): Remove.
+       (FRAME_ARGS_ADDRESS): Remove.
+       (FRAME_LOCALS_ADDRESS): Remove.
+       (FRAME_NUM_ARGS): Remove.
+       (FRAME_ARGS_SKIP): Remove.  
+       * m68k-tdep.c (enum): Add eumeration of special register numbers.
+       (m68k_gdbarch_init): Add gdbarch initializations for macros
+       undefined in tm-m68k.h
+
+2002-06-26  Grace Sainsbury  <graces@redhat.com>
+
+       * monitor.h: Add the function regname to monitor_ops
+       structure. This way NUM_REGS does not have to be a constant.
+       * monitor.c (monitor_fetch_register): Added support for regname
+       function. The function is called if the array regnames is NULL.
+       (monitor_store_register): Same.
+       * cpu32bug-rom.c (cpu32bug_regname): Add function. Replaces
+       regnames array.
+       (init_cpu32bug_cmds): set cpu32bug_cmds.regnames to NULL,
+       cpu32bug_cmds.regname to point to new function.
+       * abug-rom.c (abug_regname): Same as above.
+       (init_abug_cmds): Same.
+       * dbug-rom.c (dbug_regname): Same as above.
+       (init_dbug_cmds): Same.
+       * remote-est.c (est_regname): Same. 
+       (init_est_cmds): Same.
+       * rom68k-rom.c (rom68k_regname): Same. 
+       (init_rom68k_cmds): Same.
+
+2002-06-25  Tom Tromey  <tromey@redhat.com>
+
+       * breakpoint.c (delete_command): Don't repeat `delete' commands.
+
+2002-06-25  Andrew Cagney  <cagney@redhat.com>
+
+       * infrun.c (stop_registers): Change variable's type to ``struct
+       regcache'''.
+       (xmalloc_inferior_status): Delete function.
+       (free_inferior_status): Delete function.
+       (normal_stop): Use regcache_cpy.
+       (struct inferior_status): Change type of fields ``stop_registers''
+       and ``registers'' to ``struct regcache''.
+       (write_inferior_status_register): Use regcache_write.
+       (save_inferior_status): Instead of calling
+       xmalloc_inferior_status, allocate the inf_status buffer directly.
+       Use regcache_dup_no_passthrough and regcache_dup to save the
+       buffers.
+       (restore_inferior_status): Use regcache_xfree and regcache_cpy.
+       Replace the stop_registers regcache instead of overriding it.  Use
+       regcache_xfree.  Instead of calling free_inferior_status, xfree
+       the buffer directly.
+       (discard_inferior_status): Use regcache_xfree.  Instead of calling
+       free_inferior_status, xfree the buffer directly.
+       (build_infrun): Use regcache_xmalloc.
+       (_initialize_infrun): Delete redundant call to build_infrun.
+
+       * Makefile.in (infcmd.o): Add $(regcache_h).
+
+       * infcmd.c: Include "regcache.h".
+       (run_stack_dummy): Use deprecated_grub_regcache_for_registers to
+       obtain the address of `stop_registers' register buffer.
+       (print_return_value): Ditto.
+
+       * inferior.h (struct regcache): Add opaque declaration.
+       (stop_registers): Change variable's declared type to ``struct
+       regcache''.
+
+2002-06-24  Tom Tromey  <tromey@redhat.com>
+
+       * cli/cli-decode.c (add_show_from_set): Fixed typo in comment.
+       * target.c (initialize_targets): Fixed typo in
+       trust-readonly-sections `show' documentation.
+
+       * main.c: Marked all strings with _().
+
+2002-06-24  Don Howard  <dhoward@redhat.com>
+
+        * memattr.c (create_mem_region): Treat hi == 0 as a special case
+        that means max CORE_ADDR+1.
+        (lookup_mem_region): Ditto.
+        (mem_info_command): Ditto.
+
+2002-06-24  Grace Sainsbury  <graces@redhat.com>
+
+       * config/m68k/tm-m68k.h (DECR_PC_AFTER_BREAK): Remove.
+       (REGISTER_BYTES_OK): Remove.
+       (REGISTER_BYTES): Remove.
+       (STORE_STRUCT_RETURN): Remove.
+       (DEPRECATED_EXTRACT_RETURN_VALUE): Remove.
+       (STORE_RETURN_VALUE): Remove.
+       (DEPRECATED_EXTRACT_STRUCT_VALUE_ADDRESS): Remove.
+       (FRAME_CHAIN): Remove.
+       (FRAMELESS_FUNCTION_INVOCATION): Remove.
+       (FRAME_SAVED_PC): Remove.  
+       * m68k-tdep.c (m68k_register_bytes_ok):Add.
+       (m68k_store_struct_return): Add.
+       (m68k_deprecated_extract_return_value): Add.
+       (m68k_deprecated_extract_struct_value_address): Add.
+       (m68k_store_return_value): Add.
+       (m68k_frame_chain): Add.
+       (m68k_frameless_function_invocation): Add.
+       (m68k_frame_saved_pc): Add.
+       (m68k_gdbarch_init): added set_gdbarch calls for new 
+       functions and deleted macros.
+
+2002-06-23  Tom Tromey  <tromey@redhat.com>
+
+       * Makefile.in (HFILES_NO_SRCDIR): Remove old files.
+       (ALLDEPFILES): Likewise.
+       (udiheaders): Removed.
+       (udip2soc.o): Likewise.
+       (udi2go32.o): Likewise.
+       (udr.o): Likewise.
+       (HFILES_WITH_SRCDIR): Don't mention udiheaders.
+
+2002-06-22  Andrew Cagney  <ac131313@redhat.com>
+
+       * infrun.c (_initialize_infrun): Delete unnecessary call to
+       build_infrun.
+
+       * regcache.h: Update comments describing the regcache_cpy family
+       of functions.
+       (regcache_save, regcache_restore): Delete declaration.
+       (regcache_save_no_passthrough): Delete declaration.
+       (regcache_restore_no_passthrough): Delete declaration.
+       * regcache.c (regcache_save): Delete function.
+       (regcache_save_no_passthrough): Delete function.
+       (regcache_restore): Delete function.
+       (regcache_restore_no_passthrough): Delete function.
+
+2002-06-21  Andrew Cagney  <ac131313@redhat.com>
+
+       * config/m68k/tm-m68k.h: Fix typo.
+       (FRAME_INIT_SAVED_REGS): Define when non-multi-arch.
+       (m68k_frame_init_saved_regs): Declare.
+
+2002-06-21  Jim Blandy  <jimb@redhat.com>
+
+       Remove some vestiges of Harris 88k support.
+       * dwarf2read.c (decode_locdesc): Remove `#if' block for Harris 88k
+       register numbering quirk.
+       * elfread.c (elf_symtab_read): Remove `#if' block for skipping
+       odd symbols occurring in Harris 88k ELF targets.
+
+2002-06-21  Tom Tromey  <tromey@redhat.com>
+
+       * gdb_locale.h: New file.
+       * Makefile.in (GDB_CFLAGS): Define LOCALEDIR.
+       (defs_h): Added gdb_locale.h.
+       * configure, config.in: Rebuilt.
+       * configure.in (PACKAGE): Define.
+       * defs.h: Include gdb_locale.h.
+       * main.c (captured_main): Call setlocale, bindtextdomain,
+       textdomain.
+
+2002-06-21  Dave Brolley  <brolley@redhat.com>
+
+       From Stan Shebs, Jim Blandy, Mark Salter, Kevin Buettner:
+       * config/frv/frv.mt: New file.
+       * config/frv/tm-frv.h: New file.
+       * configure.tgt: Support frv-*-*.
+       * Makefile.in (frv-tdep.o): New target.
+       * frv-tdep.c: New file.
+       * NEWS: Mention frv.
+
+2002-06-21  Dave Brolley  <brolley@redhat.com>
+
+       * MAINTAINERS: Add self to "Write After Approval" list.
+
+2002-06-21  Grace Sainsbury  <graces@redhat.com>
+
+       * config/m68k/tm-m68k.h (REGISTER_BYTE, REGISTER_RAW_SIZE)
+       (REGISTER_VIRTUAL_SIZE, MAX_REGISTER_RAW_SIZE)
+       (REGISTER_VIRTUAL_TYPE, REGISTER_NAMES, TARGET_LONG_DOUBLE_FORMAT)
+       (FUNCTION_START_OFFSET, SKIP_PROLOGUE, SAVED_PC_AFTER_CALL)
+       (INNER_THAN, STACK_ALIGN, REGISTER_SIZE): Remove macros.
+
+       * m68k-tdep.c: Include arch-utils.h
+       (m68k_register_raw_size): Add.
+       (m68k_register_virtual_size): Add.
+       (m68k_register_virtual_type): Add.
+       (m68k_register_name): Add.
+       (m68k_stack_align): Add.
+       (m68k_register_byte): Add.
+       (m68k_gdbarch_init): Add set_gdbarch calls for macros removed in
+       tm-m68k.h.
+
+2002-06-21  Grace Sainsbury  <graces@redhat.com>
+
+       * m68k-tdep.c (m68k_frame_init_saved_regs): Replace
+        m68k_find_saved_regs.
+        (m68k_pop_frame): Removed saved_regs structure, and replaced
+        references to it with frame->saved_regs.
+        (m68k_gdbarch_init): Added function calls to initialize the
+        gdbarch structure.
+       (m68k_fix_call_dummy): Add. 
+       * config/m68k/tm-m68k.h: (FRAME_FIND_SAVED_REGS): Remove.
+               (CALL_DUMMY): Remove.
+       (CALL_DUMMY_LENGTH): Remove.
+       (CALL_DUMMY_START_OFFSET): Remove.
+       (CALL_DUMMY_BREAKPOINT_OFFSET): Remove.
+       (FIX_CALL_DUMMY): Remove.
+       (PUSH_DUMMY_FRAME): Remove.
+       (POP_FRAME): Remove.
+
+2002-06-19  Pierre Muller  <muller@ics.u-strasbg.fr>
+
+       * parse.c (parse_fprintf): New function used to avoid calls to
+       fprintf in bison parser generated debug code.
+       * parser-defs.h: Declaration of new parse_fprintf function.
+       * ada-exp.y, c-exp.y, f-exp.y, jv-exp.y, m2-exp.y, p-exp.y:
+       Set YYDEBUG to 1 by default.
+       Set YYFPRINTF as parse_fprintf.
+
+2002-06-21  Michal Ludvig  <mludvig@suse.cz>
+
+       * dwarf2cfi.c (read_encoded_pointer): Don't handle pointer 
+       encoding anymore.
+       (pointer_encoding, enum ptr_encoding): New.
+       (execute_cfa_program): Take care about pointer encoding.        
+       (dwarf2_build_frame_info): Only call parse_frame_info for 
+       .debug_frame and .eh_frame.
+       (parse_frame_info): New, derived from former dwarf2_build_frame_info.
+       fixed augmentation handling, added relative addressing, 
+       ignore duplicate FDEs. Added comments.
+       * dwarf2cfi.c: Reindented.
+       
+2002-06-20  Elena Zannoni  <ezannoni@redhat.com>
+
+       * event-top.c (command_handler): Don't use space_at_cmd_start
+       unless there is sbrk() on the host. Assign time and space data
+       to union fields of the appropriate length.
+
+2002-06-20  Michal Ludvig  <mludvig@suse.cz>
+
+       * x86-64-tdep.c (x86_64_register_nr2name): Rename to 
+       x86_64_register_name. Return type changed to 'const char *'.
+       (x86_64_register_name2nr): Rename to x86_64_register_number.
+       (x86_64_gdbarch_init): Update to reflect the change.
+       * x86-64-tdep.h: Ditto.
+       * x86-64-linux-nat.c (x86_64_fxsave_offset)
+       (supply_fpregset): Ditto.
+
+2002-06-19  Andrew Cagney  <cagney@redhat.com>
+
+       * regcache.h: Update copyright.
+       (struct regcache, struct gdbarch): Add opaque declarations.
+       (current_regcache): Declare global variable.
+       (regcache_read, regcache_write): Add gdbarch parameter.
+       (regcache_save, regcache_save_no_passthrough)
+       (regcache_restore, regcache_restore_no_passthrough)
+       (regcache_dup, regcache_dup_no_passthrough)
+       (regcache_cpy, regcache_cpy_no_passthrough)
+       (deprecated_grub_regcache_for_registers)
+       (deprecated_grub_regcache_for_register_valid)
+       (regcache_valid_p): Add function declarations.
+       
+       * regcache.c: Update copyright.
+       (regcache_descr_handle): New global variable.
+       (struct regcache_descr): Define.
+       (init_legacy_regcache_descr, init_regcache_descr): New functions.
+       (regcache_descr, xfree_regcache_descr): New functions.
+       (struct regcache): Define.
+       (regcache_xmalloc, regcache_xfree): New functions.
+       (regcache_cpy, regcache_cpy_no_passthrough): New functions.
+       (regcache_dup, regcache_dup_no_passthrough): New functions.
+       (regcache_valid_p, regcache_read_as_address): New functions.
+       (deprecated_grub_regcache_for_registers): New function.
+       (deprecated_grub_regcache_for_register_valid): New function.
+       (current_regcache): New global variable.
+       (register_buffer): Add regcache parameter.  Update calls.
+       (regcache_read, regcache_write): Add regcache parameter.  Rewrite.
+       (read_register_gen, write_register_gen): Update register_buffer
+       call.  Test for legacy_p instead of gdbarch_register_read_p or
+       gdbarch_register_write_p.
+       (regcache_collect): Update register_buffer call.
+       (build_regcache): Rewrite.  Use deprecated grub functions.
+       (regcache_save, regcache_save_no_passthrough): New functions.
+       (regcache_restore, regcache_restore_no_passthrough): New
+       functions.
+       (_initialize_regcache): Create the regcache_data_handle. Swap
+       current_regcache global variable.
+       
+       * sh-tdep.c (sh_pseudo_register_read): Add current_regcache
+       parameter to regcache_read and regcache_write calls.
+       (sh4_register_read): Ditto.
+       (sh64_pseudo_register_read): Ditto.
+       (sh64_register_read): Ditto.
+       (sh_pseudo_register_write): Ditto.
+       (sh4_register_write): Ditto.
+       (sh64_pseudo_register_write): Ditto.
+       (sh64_register_write): Ditto.
+
+       * defs.h (XCALLOC): Define.
+
+2002-06-19  Grace Sainsbury  <graces@redhat.com>
+
+       * config/m68k/tm-m68k.h (GDB_MULTI_ARCH): Added (set to 0).
+       * m68k-tdep.c (m68k_gdbarch_init): Added.
+       (m68k_dump_tdep): Added.
+
+2002-06-19  Daniel Jacobowitz  <drow@mvista.com>
+
+       * ada-lang.c (fill_in_ada_prototype): Update comment.
+
+2002-06-19  Daniel Jacobowitz  <drow@mvista.com>
+
+       * mips-tdep.c (enum mips_abi): Explicitly start at 0.  Add
+       MIPS_ABI_LAST.
+       (mips_abi_string, mips_abi_strings): New.
+       (struct gdbarch_tdep): Remove mips_abi_string, add found_abi.
+       (mips_gdbarch_init): Set tdep->found_abi.  Don't set
+       tdep->mips_abi_string.  Honor mips_abi_string.  Default to
+       O32 if no ABI is found.
+       (mips_dump_tdep): Use mips_abi_strings.
+       (mips_abi_update): New function.
+       (_initialize_mips_tdep): Initialize mips_abi_string.  Add  
+       ``set mips abi'' and ``show mips abi''.  Check the size of
+       mips_abi_strings.
+
+2002-06-19  Andrew Cagney  <cagney@redhat.com>
+
+       * i386-linux-tdep.c (i386_linux_register_name): Make return type
+       constant.
+
+2002-06-18  Joel Brobecker  <brobecker@gnat.com>
+
+       * alpha-tdep.c (heuristic_proc_desc): Compute the size of the  
+       current frame using only the first stack size adjustment. All
+       subsequent size adjustments are not considered to be part of
+       the "static" part of the current frame.
+       Compute the address of the saved registers relative to the
+       Frame Pointer ($fp) instead of the Stack Pointer if $fp is
+       in use in this frame.
+
+2002-06-18  Don Howard  <dhoward@redhat.com>
+        * valops.c (value_ind): Use value_at_lazy() when dereferencing
+        type int expressions.  Thanks to Jim Blandy <jimb@redhat.com> for
+        suggesting this solution.
+
+2002-06-18  Andrew Cagney  <ac131313@redhat.com>
+
+       * config/romp/xm-rtbsd.h: Delete file.
+       * config/romp/rtbsd.mh: Delete file.
+
+2002-06-18  Keith Seitz  <keiths@redhat.com>
+
+       * breakpoint.c (condition_command): Post breakpoint_modify
+       when a condition is added to an existing breakpoint.
+       (commands_command): Likewise for commands.
+       (set_ignore_count): Likewise for ignore counts.
+       If no tty, do not simply return, still need to send event
+       notification.
+       (ignore_command): Only print a newline if the command came
+       from a tty.
+       Don't call breakpoints_changed, since this is now properly
+       handled by set_ignore_count.
+
+2002-06-18  Andrew Cagney  <cagney@redhat.com>
+
+       * MAINTAINERS: Note that cris-elf target can be compiled with
+       -Werror.
+       * cris-tdep.c (cris_register_name): Make return type constant.
+       (cris_breakpoint_from_pc): Ditto.
+
+2002-06-18  Michal Ludvig  <mludvig@suse.cz>
+
+       * frame.h (struct frame_info): Change type of context to 
+       'struct context'.
+
+2002-06-17  Andrew Cagney  <cagney@redhat.com>
+
+       * gdbarch.sh (REGISTER_NAME): Change return type a constant string
+       pointer.
+       * gdbarch.h, gdbarch.c: Regenerate.
+       * config/mips/tm-mips.h (mips_register_name): Update.
+       * i386-tdep.h (i386_register_name): Update.
+       * mips-tdep.c (mips_register_name): Update
+       * alpha-tdep.c (alpha_register_name): Update.
+       * arch-utils.c (legacy_register_name): Update.
+       * arch-utils.h (legacy_register_name): Update.
+       * avr-tdep.c (avr_register_name): Update.
+       * ia64-tdep.c (ia64_register_name): Update.
+       * i386-tdep.c (i386_register_name): Update.
+       * sparc-tdep.c (sparc32_register_name): Update.
+       (sparc64_register_name): Update.
+       (sparclite_register_name): Update.
+       (sparclet_register_name): Update.
+       * sh-tdep.c (sh_generic_register_name): Update.
+       (sh_sh_register_name): Update.
+       (sh_sh3_register_name): Update.
+       (sh_sh3e_register_name): Update.
+       (sh_sh_dsp_register_name): Update.
+       (sh_sh3_dsp_register_name): Update.
+       (sh_sh4_register_name): Update.
+       (sh_sh64_register_name): Update.
+       * s390-tdep.c (s390_register_name): Update.
+       * rs6000-tdep.c (rs6000_register_name): Update.
+       * ns32k-tdep.c (ns32k_register_name_32082): Update.
+       (ns32k_register_name_32382): Update.
+       * d10v-tdep.c (d10v_ts2_register_name): Update.
+       (d10v_ts3_register_name): Update.
+       * xstormy16-tdep.c (xstormy16_register_name): Update.
+       * vax-tdep.c (vax_register_name): Update.
+       * v850-tdep.c (v850_register_name): Update.
+       * m68hc11-tdep.c (m68hc11_register_name): Update.
+       * mn10300-tdep.c (mn10300_generic_register_name): Update.
+       (am33_register_name): Update.
+
+2002-06-17  Grace Sainsbury  <graces@redhat.com>
+
+       * m68k-tdep.c: Reindented.
+
+2002-06-17  Andrew Cagney  <ac131313@redhat.com>
+
+       * gdb_indent.sh: Add prgregset_t, fpregset_t, and gregset_t to the
+       list of predefined types.
+
+2002-06-16  Mark Kettenis  <kettenis@gnu.org>
+
+       * config/i386/tm-i386.h (REGISTER_VIRTUAL_TYPE,
+       REGISTER_CONVERTIBLE, REGISTER_CONVERT_TO_VIRTUAL,
+       REGISTER_CONVERT_TO_RAW): Remove defines.
+       (i386_register_virtual_type, i386_register_convertible,
+       i386_register_convert_to_virtual, i386_register_convert_to_raw):
+       Remove prototypes.
+       * i386-tdep.c (i386_gdbarch_init): Adjust for removal of the
+       macros mentioned above.
+
+       * config/i386/tm-i386lynx.h (SAVED_PC_AFTER_CALL): Remove define.
+       (i386lynx_saved_pc_after_call): Remove prototype.
+       * i386ly-tdep.c: Include "i386-tdep.h".
+       (i386lynx_saved_pc_after_call): Make static.  Use
+       read_memory_nobpt instead of read_memory.  Use
+       read_memory_unsigned_integer instead of read_memory_integer.
+       (i386lynx_init_abi): New function.
+       (i386lynx_coff_osabi_sniffer): New function.
+       (_initialize_i386bsd_tdep): New function.
+
+       * config/i386/tm-i386.h (PARM_BOUNDARY, CALL_DUMMY,
+       CALL_DUMMY_LENGTH, CALL_DUMMY_START_OFFSET,
+       CALL_DUMMY_BREAKPOINT_OFFSET, FIX_CALL_DUMMY): Remove defines.
+       (i386_fix_call_dummy): Remove prototype.
+       * i386-tdep.c (i386_call_dummy_words): New variable.
+       (i386_gdbarch_init): Adjust for removal of the
+       macros mentioned above.
+
+2002-06-15  Andrew Cagney  <ac131313@redhat.com>
+
+       * command.h (add_setshow_auto_boolean_cmd): Replace
+       add_set_auto_boolean_cmd.
+       * cli/cli-decode.c (add_setshow_auto_boolean_cmd): Replace
+       add_set_auto_boolean_cmd.
+       * cli/cli-decode.h (add_set_auto_boolean_cmd): Delete declaration.
+       * mips-tdep.c (_initialize_mips_tdep): Update ``set mips
+       mask-address'' command.
+       (show_mask_address): Add cmd parameter.
+       * remote.c (add_packet_config_cmd): Update.  Change type of
+       set_func and show_func to cmd_sfunc_ftype.
+       (_initialize_remote): Update `set remote Z-packet'
+       (show_remote_protocol_qSymbol_packet_cmd): Add cmd parameter.
+       (show_remote_protocol_e_packet_cmd): Ditto.
+       (show_remote_protocol_E_packet_cmd): Ditto.
+       (show_remote_protocol_P_packet_cmd): Ditto.
+       (show_remote_protocol_Z_software_bp_packet_cmd): Ditto.
+       (show_remote_protocol_Z_hardware_bp_packet_cmd): Ditto.
+       (show_remote_protocol_Z_write_wp_packet_cmd): Ditto.
+       (show_remote_protocol_Z_read_wp_packet_cmd): Ditto.
+       (show_remote_protocol_Z_access_wp_packet_cmd): Ditto.
+       (show_remote_protocol_Z_packet_cmd): Ditto.
+       (show_remote_protocol_binary_download_cmd): Ditto.
+       (show_remote_cmd): Pass NULL to all of above.
+
+2002-06-15  Mark Kettenis  <kettenis@gnu.org>
+
+       * config/i386/tm-i386.h (PUSH_ARGUMENTS, STORE_STRUCT_RETURN,
+       DEPRECATED_EXTRACT_RETURN_VALUE, STORE_RETURN_VALUE,
+       DEPRECATED_EXTRACT_STRUCT_VALUE_ADDRESS, PUSH_DUMMY_FRAME,
+       POP_FRAME): Remove defines.
+       (i386_push_arguments, i386_store_struct_return,
+       i386_extract_return_value, i386_store_return_value,
+       i386_extract_struct_value_address, i386_push_dummy_frame,
+       i386_pop_frame): Renove prototypes.
+       * i386-tdep.c (i386_gdbarch_init): Adjust for removal of the
+       macros mentioned above.
+
+2002-06-15  Andrew Cagney  <ac131313@redhat.com>
+
+       * cli/cli-decode.c (add_setshow_boolean_cmd): Replace
+       add_set_boolean_cmd.
+       (add_setshow_cmd): New function.
+       * command.h (add_setshow_boolean_cmd): Replace
+       add_set_boolean_cmd.
+       * remote-rdi.c (_initialize_remote_rdi): Update ``set rdiheartbeat''
+       and ``set rdiromatzero''.
+       * maint.c (_initialize_maint_cmds): Update commented out code.
+       * cli/cli-decode.h (add_set_boolean_cmd): Delete declaration.
+       * target.c (initialize_targets): Update `set
+       trust-readonly-sections'.
+       * remote.c (_initialize_remote): Update `set remotebreak'.
+
+2002-06-15  Mark Kettenis  <kettenis@gnu.org>
+
+       * config/i386/tm-i386.h (FUNCTION_START_OFFSET, INNER_THAN,
+       BREAKPOINT, DECR_PC_AFTER_BREAK): Removed.
+       * i386-tdep.c (i386_skip_prologue): Adjust function signature to
+       fit into multi-arch framework.
+       (i386_breakpoint_from_pc): New function.
+       (i386_gdbarch_init): Adjust for removal of the macros mentioned
+       above.
+
+       * config/i386/tm-i386.h (FRAMELESS_FUNCTION_INVOCATION,
+       FRAME_ARGS_ADDRESS, FRAME_LOCALS_ADDRESS, FRAME_NUM_ARGS,
+       FRAME_ARGS_SKIP, FRAME_INIT_SAVED_REGS): Remove defines.
+       (i386_frameless_function_invocation, i386_frame_num_args,
+       i386_frame_init_saved_regs): Remove prototypes.
+       * i386-tdep.c (i386_gdbarch_init): Adjust for removal of the
+       macros mentioned above.
+
+2002-06-15  Andrew Cagney  <ac131313@redhat.com>
+
+       * cli/cli-decode.c (set_cmd_cfunc): Update.
+       (set_cmd_sfunc): Update.
+       * command.h (cmd_cfunc_ftype, cmd_sfunc_ftype): Declare.
+       (set_cmd_sfunc, set_cmd_cfunc): Update.
+       * cli/cli-decode.h: Update.
+
+2002-06-15  Mark Kettenis  <kettenis@gnu.org>
+
+       * i386-sol2-tdep.c (i386_sol2_osabi_sniffer): New function.
+       (_initialize_i386_sol2_tdep): Register i386_sol2_osabi_sniffer.
+
+2002-06-15  Andrew Cagney  <ac131313@redhat.com>
+
+       * defs.h (auto_boolean): Declare enum.
+       * command.h (cmd_auto_boolean): Delete enum.
+       * mips-tdep.c (mask_address_var): Update.
+       (mips_mask_address_p): Update.
+       (show_mask_address): Update.
+       * remote.c (struct packet_config): Update.
+       (update_packet_config): Update.
+       (show_packet_config_cmd): Update.
+       (packet_ok): Update.
+       (add_packet_config_cmd): Update.
+       (_initialize_remote): 
+       * command.h: Update.
+       * cli/cli-setshow.c (parse_auto_binary_operation): Update.
+       (do_setshow_command): Update.
+       * cli/cli-decode.c (add_set_auto_boolean_cmd): Update.
+       * cli/cli-decode.h: Update.
+
+2002-06-15  Mark Kettenis  <kettenis@gnu.org>
+
+       * config/i386/tm-cygwin.h, config/i386/tm-fbsd.h,
+       config/i386/tm-go32.h, config/i386/tm-i386gnu.h,
+       config/i386/tm-i386sol2.h, config/i386/tm-i386v4.h,
+       config/i386/tm-linux.h, config/i386/tm-nbsd.h,
+       config/i386/tm-obsd.h (HAVE_I387_REGS): Remove define.
+       * config/i386/tm-i386.h: Unconditionally define FLOAT_INFO.
+
+       * i386-tdep.c (i386_coff_osabi_sniffer): Add "coff-go32" to the
+       list of DJGPP COFF targets.
+
+       * config/i386/tm-i386.h (REGISTER_SIZE): Remove define.
+       (NUM_GREGS, NUM_FREGS, NUM_SSE_REGS): Remove defines.
+       (FP_REGNUM, SP_REGNUM, PC_REGNUM, PS_REGNUM): Remove defines.
+       (FP0_REGNUM): Remove define.
+       (MAX_REGISTER_RAW_SIZE, MAX_REGISTER_VIRTUAL_SIZE,
+       MAX_REGISTER_VIRTUAL_SIZE): Remove define.
+       (i386_register_virtual_size): Remove protoype.
+       * i386-tdep.c (i386_register_virtual_size): Removed.
+       (i386_extract_return_value, i386_store_return_value): Use
+       FP0_REGNUM instead of NUM_FREGS to determine whether the
+       floating-point registers are available.
+       (i386_gdbarch_init): Tweak FIXME about FPU registers.
+       Adjust for removal of macros mentioned above.
+
+2002-06-15  Mark Kettenis  <kettenis@gnu.org>
+
+       * i386v4-nat.c: Include "i386-tdep.h".  Reformat and tweak various
+       comments.
+       (fill_gregset, supply_gregset, supply_fpregset, fill_fpregset):
+       Remove prototypes.
+       (supply_gregset, fill_gregset): Remove use of register keyword and
+       remove declaration for regmap.  Use I386_NUM_GREGS instead of
+       NUM_REGS and NUM_FREGS.
+       (FPREGSET_FSAVE_OFFSET): Remove.
+       (supply_fpregset, fill_fpregset): Use FPO_REGNUM instead of
+       NUM_FREGS to determine whether the floating-point registers are
+       available.
+
+       * i386gnu-nat.c (supply_gregset, gnu_fetch_registers,
+       gnu_store_registers): Replace usage of NUM_GREGS with
+       I386_NUM_GREGS.
+
+       * i386-linux-nat.c (OLD_CANNOT_FETCH_REGISTER,
+       OLD_CANNOT_STORE_REGISTER, supply_gregset, fill_gregset): Replace
+       usage of NUM_GREGS with I386_NUM_GREGS.
+
+       * i386-linux-nat.c (fill_gregset): Remove redundant parentheses.
+
+       * i386bsd-nat.c: Include "i386-tdep.h".
+       (supply_gregset, fill_gregset): Replace usage of NUM_GREGS with
+       I386_NUM_GREGS.
+
+       * i386v-nat.c: Remove copnditional inclusion of <asm/debugreg.h>,
+       and associated comment.  They no longer make any sense, since we
+       don't use this file anymore on Linux.
+
+       * config/i386/tm-i386.h (MAX_NUM_REGS): Removed.
+       * i386-tdep.c (i386_register_offset, i386_register_size): Use
+       I386_SSE_NUM_REGS instead of MAX_NUM_REGS for the number of
+       elements in these arrays.
+       (_initialize_i386_tdep): Use I386_SSE_NUM_REGS instead of
+       MAX_NUM_REGS.
+
+2002-06-15  Mark Kettenis  <kettenis@gnu.org>
+
+       * osabi.h (gdb_osabi): Add GDB_OSABI_LYNXOS.
+       * osabi.c (gdb_osabi_names): Add entry for "LynxOS".
+
+2002-06-14  Andrew Cagney  <cagney@redhat.com>
+
+       * gdbarch.sh (DEPRECATED_EXTRACT_RETURN_VALUE): Rename
+       EXTRACT_RETURN_VALUE.
+       (DEPRECATED_EXTRACT_STRUCT_VALUE_ADDRESS): Rename
+       EXTRACT_STRUCT_VALUE_ADDRESS.
+       * gdbarch.h, gdbarch.c: Regenerate.
+       
+       * values.c (value_being_returned): Handle
+       DEPRECATED_EXTRACT_STRUCT_VALUE_ADDRESS.
+       (EXTRACT_RETURN_VALUE): Define as DEPRECATED_EXTRACT_RETURN_VALUE.
+
+       * arm-linux-tdep.c (arm_linux_init_abi): Update. 
+       * arm-tdep.c (arm_gdbarch_init): Update.
+       * avr-tdep.c (avr_gdbarch_init): Update.
+       * cris-tdep.c (cris_gdbarch_init): Update.
+       * d10v-tdep.c (d10v_gdbarch_init): Update.
+       * ia64-tdep.c (ia64_gdbarch_init): Update.
+       * m68hc11-tdep.c (m68hc11_gdbarch_init): Update.
+       * rs6000-tdep.c (rs6000_gdbarch_init): Update.
+       * s390-tdep.c (s390_gdbarch_init): Update.
+       * sh-tdep.c (sh_gdbarch_init): Update.
+       * s390-tdep.c (s390_gdbarch_init): Update.
+       * sparc-tdep.c (sparc_gdbarch_init): Update.
+       * ns32k-tdep.c (ns32k_gdbarch_init): Update.
+       * v850-tdep.c (v850_gdbarch_init): Update.
+       * vax-tdep.c (vax_gdbarch_init): Update.
+       * x86-64-tdep.c (x86_64_gdbarch_init): Update.
+       * xstormy16-tdep.c (xstormy16_gdbarch_init): Update.
+
+       * config/arc/tm-arc.h: Update.
+       * config/d30v/tm-d30v.h: Update.
+       * config/fr30/tm-fr30.h: Update.
+       * config/h8300/tm-h8300.h: Update.
+       * config/h8500/tm-h8500.h: Update.
+       * config/i386/tm-i386.h: Update.
+       * config/i386/tm-ptx.h: Update.
+       * config/i386/tm-symmetry.h: Update.
+       * config/i960/tm-i960.h: Update.
+       * config/m32r/tm-m32r.h: Update.
+       * config/m68k/tm-delta68.h: Update.
+       * config/m68k/tm-linux.h: Update.
+       * config/m68k/tm-m68k.h: Update.
+       * config/m88k/tm-m88k.h: Update.
+       * config/mcore/tm-mcore.h: Update.
+       * config/mips/tm-mips.h: Update.
+       * config/mn10200/tm-mn10200.h: Update.
+       * config/pa/tm-hppa.h: Update.
+       * config/pa/tm-hppa64.h: Update.
+       * config/sparc/tm-sp64.h: Update.
+       * config/sparc/tm-sparc.h: Update.
+       * config/sparc/tm-sparclet.h: Update.
+       * config/z8k/tm-z8k.h: Update.
+
+2002-06-14  Andrew Cagney  <cagney@redhat.com>
+
+       * Makefile.in (i386_linux_tdep_h): Define.
+       (i386_tdep_h, i387_tdep_h): Define.
+       (i386-linux-nat.o): Add $(i386_linux_tdep_h),
+       $(i386_tdep_h) and $(i387_tdep_h).
+       * i386-linux-nat.c: Include "i386-linux-tdep.h".
+
+2002-06-14  Mark Kettenis  <kettenis@gnu.org>
+
+       * config/i386/tm-i386.h (START_INFERIOR_TRAPS_EXPECTED): Removed.
+       Already covered by the default.
+
+       * config/i386/tm-i386.h (TARGET_LONG_DOUBLE_FORMAT,
+       TARGET_LONG_DOUBLE_BIT): Remove.  * i386-tdep.c
+       (i386_gdbarch_init): Initialize long_double_format and long_double
+       bit.
+
+       * config/i386/i386sol2.mt (TDEPFILES): Add i386-sol2-tdep.o and
+       i386bsd-tdep.o.  Remove solib.o, solib-svr4.o and solib-legacy.o.
+       Move these to ...
+       * config/i386/i386sol2.mh: ... here.
+       * config/i386/tm-i386sol2.h (STAB_REG_TO_REGNUM): Remove define.
+       (sigtramp_saved_pc, I386V4_SIGTRAMP_SAVED_PC): Don't #undef.
+       (SIGCONTEXT_PC_OFFSET): Remove define.
+       (IN_SIGTRAMP): Remove define.
+       * i386-sol2-tdep.c: New file.
+       
+       * config/i386/i386nw.mt (TM_FILE): Change to tm-i386.h.
+       * config/i386/tm-i386nw.h: Removed.
+
+       * config/i386/tm-fbsd.h (STAB_REG_TO_REGNUM,
+       USE_STRUCT_CONVENTION): Remove defines.
+       (JB_ELEMENT_SIZE, JB_PC, GET_LONGJMP_TARGET): Remove defines.
+       (get_longjmp_target): Remove prototype.
+       (IN_SIGTRAMP): Remove define.
+       (i386bsd_in_sigtramp): Remove prototype.
+       (i386bsd_sigtramp_start, i386bsd_sigtramp_end): Turn into a
+       function.  Update comment accordingly
+       (SIGTRAMP_START, SIGTRAMP): Adjust definition accordingly.
+       (FRAME_SAVED_PC): Remove define.
+       (i386bsd_frame_saved_pc): Remove prototype.
+       * config/i386/tm-nbsd.h (JB_ELEMENT_SIZE, JB_PC,
+       GET_LONGJMP_TARGET): Remove defines.
+       (get_longjmp_target): Remove prototype.
+       (IN_SIGTRAMP): Remove define.
+       (i386bsd_in_sigtramp): Remove prototype.
+       (i386bsd_sigtramp_start, i386bsd_sigtramp_end): Turn into a
+       function.  Update comment accordingly
+       (SIGTRAMP_START, SIGTRAMP): Adjust definition accordingly.
+       (FRAME_SAVED_PC): Remove define.
+       (i386bsd_frame_saved_pc): Remove prototype.
+       * config/i386/tm-nbsdaout.h (i386nbsd_aout_use_struct_convention):
+       Remove prototype.
+       (USE_STRUCT_CONVENTION): Remove prototype.
+       * i386bsd-nat.c (i386bsd_sigcontext_pc_offset): Remove
+       declaration.
+       (_initialize_i386bsd_nat): Revise logic to determine some
+       constants at compile time when compiling a native GDB.  Warn if
+       things don't match up with what we expect.
+       * i386bsd-tdep.c (i386bsd_sigtramp_start, i386bsd_sigtramp_end):
+       Remove variables.
+       (i386bsd_in_sigtramp): Rename tp i386bsd_pc_in_sigtramp.  Rewrite
+       to use date stored in `struct gdbarch_tdep'.
+       (i386bsd_sigcontext_offset): Remove varaible.
+       (i386bsd_sigtramp_saved_pc): Make public.  Rewrite to use data
+       stored in `struct gdbarch_tdep'.
+       (i386bsd_frame_saved_pc): Make static.
+       (i386bsd_sigtramp_start, i386bsd_sigtramp_end): New functions.
+       (i386bsd_sc_pc_offset, i386nbsd_sc_pc_offset,
+       i386fbsd_sigtramp_start, i386fbsd_sigtramp_end,
+       i386fbsd4_sc_pc_offset): New variables.
+       (i386bsd_init_abi, i386nbsd_init_abi, i386nbsdelf_init_abi,
+       i386fbsdaout_init_abi, i386fbsd_init_abi, i386fbsd4_init_abi): New
+       functions.
+       (i386bsd_aout_osabi_sniffer, _initialize_i386bsd_tdep): New
+       functions.
+       * i386fbsd-nat.c (_initialize_i386fbsd_nat): Fix type in comment.
+       Modify the value of i386fbsd_sigtramp_start and
+       i386fbsd_sigtramp_end instead of i386bsd_sigtramp_start and
+       i386fbsd_sigtramp_end.
+       * i386nbsd-tdep.c: (i386nbsd_aout_use_struct_convention): Remove
+       function.
+
+       * config/i386/tm-linux.h (I386_LINUX_ORIG_EAX_REGNUM): Move
+       define to i386-linux-tdep.h.
+       (NUM_REGS, MAX_NUM_REGS, REGISTER_BYTES, REGISTER_NAME,
+       REGISTER_BYTE, REGISTER_RAW_SIZE, STAB_REG_TO_REGNUM): Remove
+       defines.
+       (i386_linux_register_name, i386_linux_register_byte,
+       i386_linux_register_raw_size): Remove prototypes.
+       (i386_linux_svr4_fetch_link_map_offsets): Remove prototype.
+       (SVR4_FETCH_LINK_MAP_OFFSETS): Remove define.
+       (IN_SIGTRAMP, FRAME_CHAIN, FRAME_SAVED_PC, SAVED_PC_AFTER_CALL,
+       TARGET_WRITE_PC): Remove defines.
+       (i386_linux_in_sigtramp, i386_linux_frame_chain,
+       i386_linux_frame_saved_pc, i386_linux_saved_pc_after_call,
+       i386_linux_write_pc): Remove prototypes.
+       (JB_ELEMENT_SIZE, JB_PC, GET_LONGJMP_TARGET): Remove defines.
+       (get_longjmp_target): Remove prototype.
+       * i386-linux-tdep.h: New file.
+       * i386-linux-nat.c: Include "i386-linux-tdep.h".
+       * i386-linux-tdep.c: Include "i386-tdep.h" and
+       "i386-linux-tdep.h".
+       (i386_linux_register_name, i386_linux_register_byte,
+       i386_linux_register_raw_size, i386_linux_in_sigtramp,
+       i386_linux_write_pc, i386_linux_svr4_fetch_link_map_offsets):
+       Make static.
+       (i386_linux_init_abi): New function.
+       (_initialize_i386_linux_tdep): New function.
+
+       * config/i386/tm-i386.h (SAVED_PC_AFTER_CALL): Remove define.
+       (i386_saved_pc_after_call): Remove prototype.
+       (MAX_NUM_REGS): Increase to deal with Linux's orig_eax "register".
+       (REGISTER_NAME, STAB_REG_TO_REGNUM, SDB_REG_TO_REGNUM,
+       DWARF_REG_TO_REGNUM, DWARF2_REG_TO_REGNUM): Remove defines.
+       (i386_register_name, i386_stab_reg_to_regnum,
+       i386_dwarf_reg_to_regnum): Remove prototypes.
+       (SIZEOF_GREGS, SIZEOF_FPU_REGS, SIZEOF_FPU_CTL_REGS,
+       SIZEOF_SSE_REGS): Remove defines.
+       (REGISTER_BYTES): Remove define.
+       (REGISTER_BYTE, REGISTER_RAW_SIZE): Remove defines.
+       (i386_register_byte, i386_register_raw_size): Remove prototypes.
+       (FRAME_CHAIN, FRAME_SAVED_PC): Remove defines.
+       (i386_frame_chain, i386_frame_saved_pc): Remove prototypes.
+       * config/i386/tm-i386v4.h (FRAME_CHAIN_VALID): Remove define.
+       (JB_ELEMENT_SIZE, JB_PC, JB_EBX, JB_ESI, JB_EDI, JB_EBP, JB_ESP,
+       JB_EDX, GET_LONGJMP_TARGET): Remove defines.
+       (get_longjmp_target): Remove prototype.
+       (I386V4_SIGTRAMP_SAVED_PC, IN_SIGTRAMP): Remove defines.
+       (sigtramp_saved_pc): Remove define.
+       (i386v4_sigtramp_saved_pc): Remove prototype.
+       * config/i386/tm-go32.h (FRAME_CHAIN,
+       FRAMELESS_FUNCTION_INVOCATION, FRAME_SAVED_PC): Remove defines.
+       (i386go32_frame_saved_pc): Remove prototype.
+       (JB_ELEMENT_SIZE, JB_PC, GET_LONGJMP_TARGET): Remove defines.
+       (get_longjmp_target): Remove prototype.
+       * i386-tdep.h: Include "osabi.h".
+       (enum i386_abi): Removed.
+       (enum struct_return): New enum.
+       (struct gdbarch_tdep): Remove abi member, add osabi, jb_pc_offset,
+       struct_return, sigtramp_saved_pc, sigtramp_start, sigtramp_end and
+       sc_pc_offset members.
+       (i386_gdbarch_register_os_abi): Remove prototype.
+       (I386_NUM_GREGS, I386_NUM_FREGS, I386_NUM_XREGS,
+       I386_SSE_NUM_REGS): New defines.
+       (I386_SIZEOF_GREGS, I386_SIZEOF_FREGS, I386_SIZEOF_XREGS,
+       I386_SSE_SIZEOF_REGS): New defines.
+       (i386_register_name, i386_register_byte, i386_register_raw_size):
+       New prototypes.
+       (i386_elf_init_abi, i386_svr4_init_abi): New prototypes.
+       (i386bsd_sigtramp_saved_pc): New prototype.
+       * i386-tdep.c: Don't include "elf-bfd.h".
+       (i386_stab_reg_to_regnum, i386_dwarf_reg_to_regnum,
+       i386_frame_chain, i386_saved_pc_after_call): Make static.
+       (i386_frame_saved_pc): Rewrite to call architecture dependent
+       function to deal with signal handlers.  Make static.
+       (i386go32_frame_saved_pc): Removed.
+       [GET_LONGJMP_TARGET] (JB_PC, JB_ELEMENT_SIZE, get_longjmp_target):
+       Removed.
+       (i386_get_longjmp_target): New function.
+       (default_struct_convention, pcc_struct_convention,
+       reg_struct_convention, valid_conventions, struct_convention): New
+       variables.
+       (i386_use_struct_convention): New function.
+       (i386v4_sigtramp_saved_pc): Renamed to
+       i386_svr4_sigtramp_saved_pc.  Made static.  Moved.
+       (i386_pc_in_sigtramp): New function.
+       (i386_abi_names): Removed.
+       (ABI_TAG_OS_GNU_LINUX, ABI_TAG_OS_GNU_HURD,
+       ABI_TAG_OS_GNU_SOLARIS, ABI_TAG_OS_FREEBSD, ABI_TAG_OS_NETBSD):
+       Removed.
+       (process_note_sections, i386_elf_abi_from_note, i386_elf_abi,
+       i386_gdbarch_register_os_abi): Removed.
+       (struct i386_abi_handler): Removed.
+       (i386_abi_handler_list): Removed.
+       (i386_svr4_pc_in_sigtramp, i386_go32_pc_in_sigtramp): New
+       functions.
+       (i386_elf_init_abi, i386_svr4_init_abi, i386_go32_init_abi,
+       i386_nw_init_abi): New functions.
+       (i386_gdbarch_init): Rewritten to use generic OS ABI framework.
+       Use set_gdbarch_xxx() calls instead of relying on macros for a
+       number of calls.
+       (i386_coff_osabi_sniffer, i386_nlm_osabi_sniffer): New functions.
+       (_initialize_i386_tdep): Add new 'struct-convcention' command.
+       Register the various architecture variants defined in this file.
+
+2002-06-14  Daniel Jacobowitz  <drow@mvista.com>
+
+       * gdbtypes.h (TYPE_FLAG_VARARGS): Update comment.
+       (struct main_type): Remove arg_types member.  Update comments for
+       struct field.
+       (TYPE_ARG_TYPES): Remove.
+       (TYPE_FN_FIELD_ARGS): Update.
+       (smash_to_method_type): Update prototype.
+
+       * c-typeprint.c (cp_type_print_method_args): Take method type
+       instead of argument list.  Use new argument layout.  Simplify.
+       (c_type_print_args): Use new argument layout.  Simplify.
+       (c_type_print_base): Update call to cp_type_print_method_args.
+       * dwarf2read.c (dwarf2_add_member_fn): Remove unneeded type
+       argument; use die->type instead.  Update call to
+       smash_to_method_type.
+       (read_structure_scope): Update call to dwarf2_add_member_fn.
+       * gdbtypes.c (allocate_stub_method): Update comment.
+       (smash_to_method_type): Take new NARGS and VARARGS arguments.
+       Use new argument layout.
+       (check_stub_method): Use new argument layout.  Don't count
+       void as an argument.
+       (print_arg_types): Update comments.  Use new argument layout.
+       (recursive_dump_type): Don't print arg_types member.
+       * hpread.c (hpread_read_struct_type): Use new argument layout.
+       (fixup_class_method_type): Likewise.
+       (hpread_type_lookup): Likewise.
+       * stabsread.c (read_type): Update calls to read_args and
+       smash_to_method_type.
+       (read_args): Use new argument layout.  Simplify.
+       * valops.c (typecmp): Use new argument layout.  Update parameters
+       and comments.  Simplify.
+       (hand_function_call): Use new argument layout.
+       (search_struct_method): Update call to typecmp.
+       (find_overload_match): Use new argument layout.
+
+2002-06-13  Daniel Jacobowitz  <drow@mvista.com>
+
+       * NEWS: Mention multithreaded debug support for gdbserver.
+
+2002-06-13  Daniel Jacobowitz  <drow@mvista.com>
+
+       * MAINTAINERS: Mention NEWS.
+
+2002-06-13  Daniel Jacobowitz  <drow@mvista.com>
+
+       * mips-tdep.c (PROC_SYMBOL): Add warning comment.
+       (struct mips_objfile_private, compare_pdr_entries): New.
+       (non_heuristic_proc_desc): Read the ".pdr" section if it
+       is present.
+
+2002-06-12  Andrew Cagney  <ac131313@redhat.com>
+
+       * arm-tdep.c (arm_push_arguments): Rewrite using a two-pass loop.
+       (arm_debug): New static variable.
+       (_initialize_arm_tdep): Add ``set debug arm'' command.
+
+2002-06-12  Andrew Cagney  <ac131313@redhat.com>
+
+       * Makefile.in (sim_arm_h): Define.
+       (arm-tdep.o): Add $(sim_arm_h) and $(gdb_assert_h).
+       * arm-tdep.c: Include "gdb/sim-arm.h" and "gdb_assert.h".
+       (arm_register_sim_regno): New function, map an internal REGNUM
+       onto a simulator register number.
+       (arm_gdbarch_init): Set register_sim_regno.
+
+2002-06-09  Aldy Hernandez  <aldyh@redhat.com>
+
+       * MAINTAINERS: Add self.
+
+2002-06-11  Jim Blandy  <jimb@redhat.com>
+
+       * source.c (source_info): Mention whether the symtab has
+       information about preprocessor macros.
+
+       Call the command `info macro', not `show macro'.
+       * macrocmd.c (info_macro_command): Renamed from `show_macro_command'.
+       Fix error message.
+       (_initialize_macrocmd): Register `info_macro_command' in
+       `infolist', not `showlist'.
+
+2002-06-11  Daniel Jacobowitz  <drow@mvista.com>
+
+       * mips-tdep.c (MIPS_FPU_TYPE, FP_REGISTER_DOUBLE, MIPS_EABI)
+       (MIPS_LAST_FP_ARG_REGNUM, MIPS_LAST_ARG_REGNUM)
+       (MIPS_DEFAULT_SAVED_REGSIZE, MIPS_REGS_HAVE_HOME_P)
+       (MIPS_DEFAULT_STACK_ARGSIZE, GDB_TARGET_IS_MIPS64)
+       (MIPS_DEFAULT_MASK_ADDRESS_P): Remove obsolete definitions.  Define
+       unconditionally.
+       (set_mipsfpu_single_command, set_mipsfpu_double_command)
+       (set_mipsfpu_none_command): Remove if (GDB_MULTI_ARCH).
+       (_initialize_mips_tdep): Remove dead code.
+       * config/mips/tm-irix5.h (MIPS_LAST_ARG_REGNUM)
+       (MIPS_DEFAULT_STACK_ARGSIZE, MIPS_REGS_HAVE_HOME_P): Remove.
+       * config/mips/tm-irix6.h (MIPS_LAST_ARG_REGNUM)
+       (MIPS_DEFAULT_STACK_ARGSIZE, MIPS_REGS_HAVE_HOME_P): Remove.
+       * config/mips/tm-mips.h (MIPS_EABI, MIPS_LAST_ARG_REGNUM,
+       MIPS_LAST_FP_ARG_REGNUM): Remove.
+
+2002-06-11  Michal Ludvig  <mludvig@suse.cz>
+
+       * dwarf2cfi.c (unwind_tmp_obstack_init): New.
+       (unwind_tmp_obstack_free, parse_frame_info)
+       (update_context, cfi_read_fp, cfi_write_fp)
+       (cfi_frame_chain, cfi_init_extra_frame_info)
+       (cfi_virtual_frame_pointer): Use the above function.
+       * dwarf2cfi.c: Reindented (using 'indent dwarf2cfi.c').
+
+2002-06-11  Corinna Vinschen  <vinschen@redhat.com>
+
+       * v850-tdep.c (v850_type_is_scalar): New function.
+       (v850_use_struct_convention): Match current gcc implementation
+       as close as possible.
+       (v850_push_arguments): Fix stack_offset handling.  Don't write
+       struct_addr into register.  This is done by v850_store_struct_return.
+       (v850_extract_return_value): Care for structs.
+       (v850_store_return_value): Ditto.
+       (v850_store_struct_return): Actually write address.
+
+2002-06-11  Michal Ludvig  <mludvig@suse.cz>
+
+       * x86-64-tdep.c (x86_64_skip_prologue): Fix to work on functions
+       without debug information too.
+
+2002-06-10  Andrew Cagney  <ac131313@redhat.com>
+
+       * gdbarch.sh (PRINT_FLOAT_INFO): Add frame and ui_file parameters.
+       Make multi-arch pure.
+       * gdbarch.h, gdbarch.c: Re-generate.
+       * arm-tdep.c (arm_print_float_info): Update.
+       * arch-utils.h (default_print_float_info): Update.
+       * arch-utils.c (default_print_float_info): Update.
+       * infcmd.c (float_info): Update call.
+
+2002-06-10  Andrew Cagney  <ac131313@redhat.com>
+
+       * Makefile.in (init.c): Move the call to _initialize_gdbtypes to
+       the front of the initialize list.
+
+2002-06-10  Andrew Cagney  <ac131313@redhat.com>
+
+       * infrun.c (struct inferior_status): Replace fields
+       selected_frame_address and selected_level with field
+       selected_frame_id.
+       (save_inferior_status): Update.  Use get_frame_id.
+       (struct restore_selected_frame_args): Delete.
+       (restore_selected_frame): Update.  Use frame_find_by_id.
+       (restore_inferior_status): Update.
+
+       * breakpoint.h (struct breakpoint): Change type of
+       watchpoint_frame to frame_id.
+       * breakpoint.c (insert_breakpoints): Use frame_find_by_id.  Remove
+       call to get_current_frame.
+       (do_enable_breakpoint): Use frame_find_by_id.  Remove call to
+       get_current_frame.
+       (watchpoint_check): Use frame_find_by_id.
+
+       * frame.h (record_selected_frame): Delete declaration.
+       * stack.c (record_selected_frame): Delete function.
+       
+       * frame.h (struct frame_id): Define.
+       (get_frame_id): Declare.
+       (frame_find_by_id): Declare.
+       * frame.c (frame_find_by_id): New function.
+       (get_frame_id): New function.
+
+2002-06-10  Andrey Volkov <avolkov@transas.com>
+
+       * ser-e7kpc.c: Fix duplicated define and call of 
+        _initialize_ser_e7000pc
+           
+2002-06-09  Daniel Jacobowitz  <drow@mvista.com>
+
+       * signals/signals.c (target_signal_from_host): Fix #ifdef
+       SIGRTMIN case.
+       (do_target_signal_to_host): Likewise.
+
+2002-06-09  Daniel Jacobowitz  <drow@mvista.com>
+
+       * mips-tdep.c (mips_find_abi_section): New function.
+       (mips_gdbarch_init): Call it.
+
+2002-06-09  Mark Kettenis  <kettenis@gnu.org>
+
+       * solib-svr4.c (init_fetch_link_map_offsets): Simply return
+       legacy_fetch_link_map_offsets.  Adjust comment to reflect reality
+       after Andrew's 2002-06-08 gdbarch change.
+
+2002-06-09  Mark Kettenis  <kettenis@gnu.org>
+
+       * i386-linux-nat.c (suppy_gregset): Don't supply
+       I386_LINUX_ORIG_EAX_REGNUM if there isn't room for it in GDB's
+       register cache.
+       (fill_gregset): Don't fetch it under the same circumstances.
+
+2002-06-09  Andrew Cagney  <cagney@redhat.com>
+
+       * Makefile.in (callback_h): Define.
+       (remote_sim_h): Update path to remote-sim.h.
+       (remote-rdp.o): Add $(callback_h).
+       (remote-sim.o): Use $(callback_h).
+       * remote-sim.c: Include "gdb/callback.h" and "gdb/remote-sim.h".
+       * remote-rdp.c: Include "gdb/callback.h".
+
+2002-06-09  Mark Kettenis  <kettenis@gnu.org>
+
+       * osabi.h (gdb_osabi): Add GDB_OSABI_GO32 and GDB_OSABI_NETWARE.
+       * osabi.c (gdb_osabi_names): Add "DJGPP" and "NetWare".
+
+2002-06-08  Andrew Cagney  <ac131313@redhat.com>
+
+       * sparcl-tdep.c: Use __CYGWIN__ instead of __CYGWIN32__.
+       * rdi-share/serpardr.c: Ditto.
+       * rdi-share/unixcomm.c: Ditto.
+       * rdi-share/serdrv.c: Ditto.
+       * rdi-share/hostchan.h: Ditto.
+       * rdi-share/hostchan.c: Ditto.
+       * rdi-share/host.h: Ditto.
+       * rdi-share/devsw.c: Ditto.
+
+       * objfiles.h: Change type of obj_private to void pointer.
+       * pa64solib.c: Update copyright.  Don't include "assert.h", use
+       strcmp instead of STREQ, use LONGEST, do not use PTR
+       * somsolib.c: Ditto.
+
+       * config/djgpp/fnchange.lst: Fix problems with bfd/elf32-i386.c,
+       bfd/elf32-i386qnx.c, bfd/elf32-sh.c, bfd/elf32-sh64-nbsd.c,
+       bfd/elf64-sh64-nbsd.c bfd/elf64-sh64.c.
+
+2002-06-08  Andrew Cagney  <ac131313@redhat.com>
+
+       * frame.c (GET_SAVED_REGISTER): Delete macro definition.
+       (default_get_saved_register): Delete function.
+       * gdbarch.sh (GET_SAVED_REGISTER): Set default to
+       generic_unwind_get_saved_register.
+       * gdbarch.h, gdbarch.c: Re-generate.
+       
+2002-06-08  Andrew Cagney  <ac131313@redhat.com>
+
+       * gdbarch.sh (FRAME_CHAIN_VALID): Set default to
+       generic_func_frame_chain_valid.
+       * gdbarch.h, gdbarch.c: Re-generate.
+       * blockframe.c (generic_func_frame_chain_valid): Only check
+       PC_IN_CALL_DUMMY when generic dummy frames.  Don't worry about
+       passing FP to PC_IN_CALL_DUMMY.
+       Fix PR gdb/360.
+
+2002-06-08  Andrew Cagney  <ac131313@redhat.com>
+
+       * gdbarch.sh (struct gdbarch_data): Add field init_p.
+       (register_gdbarch_data): Initialize init_p.
+       (gdbarch_data): Initialize data pointer using the init function.
+       (init_gdbarch_data): Delete function.
+       (gdbarch_update_p): Update.
+       (initialize_non_multiarch): Update.
+       (struct gdbarch): Add field initialized_p.
+       * gdbarch.h, gdbarch.c: Re-generate.
+
+2002-06-07  Michal Ludvig  <mludvig@suse.cz>
+
+       * x86-64-linux-nat.c (x86_64_fxsave_offset): New.
+       (supply_fpregset, fill_fpregset): Don't call i387_*_fxsave,
+       better do the things actually here.
+       * x86-64-tdep.c (x86_64_register_name2nr): New.
+       (x86_64_register_name): Renamed to x86_64_register_nr2name.
+       (x86_64_gdbarch_init): Respect the above change.
+       * x86-64-tdep.h (x86_64_register_name2nr)
+       (x86_64_register_nr2name): Add prototypes.
+       * config/i386/x86-64linux.mt (TDEPFILES): Remove i387-tdep.o.
+
+2002-06-06  Michael Snyder  <msnyder@redhat.com>
+
+       * d10v-tdep.c (d10v_push_arguments): Handle struct_return.
+       Delete extra braces and re-indent.
+       (d10v_store_return_value): Char return values
+       must be shifted over by one byte in R0.
+       (d10v_extract_return_value): Delete extra braces, re-indent.
+
+2002-06-06  Elena Zannoni  <ezannoni@redhat.com>
+
+        * d10v-tdep.c (d10v_read_sp, d10v_read_fp): Add prototype.
+        (d10v_register_virtual_type): Make $fp and $sp be pointer to data.
+        (d10v_integer_to_address): Rewrite.
+        (d10v_frame_init_saved_regs): When reading fp and sp registers use
+        the d10v specific functions which take care of converting to the
+        correct space.
+
+2002-06-06  Elena Zannoni  <ezannoni@redhat.com>
+
+       * config/djgpp/fnchange.lst: Add testsuite files altivec-abi.c,
+       altivec-abi.exp, altivec-regs.c, altivec-regs.exp.
+
+2002-06-02  Andrew Cagney  <ac131313@redhat.com>
+
+       * config/alpha/nm-linux.h: Add "config/" prefix to tm, nm and xm
+       includes.
+       * config/tm-linux.h: Ditto.
+       * config/alpha/tm-alphalinux.h: Ditto.
+       * config/arm/nm-linux.h, config/arm/tm-linux.h: Ditto.
+       * config/arm/xm-nbsd.h, config/i386/nm-gnu.h: Ditto.
+       * config/i386/nm-i386lynx.h, config/i386/nm-i386sol2.h: Ditto.
+       * config/i386/nm-i386v4.h, config/i386/nm-i386v42mp.h: Ditto.
+       * config/i386/nm-linux.h, config/i386/nm-m3.h: Ditto.
+       * config/i386/nm-ptx4.h, config/i386/nm-x86-64.h: Ditto.
+       * config/i386/tm-i386gnu.h, config/i386/tm-i386lynx.h: Ditto.
+       * config/i386/tm-i386m3.h, config/i386/tm-i386sco5.h: Ditto.
+       * config/i386/tm-i386v4.h, config/i386/tm-linux.h: Ditto.
+       * config/i386/tm-ptx4.h, config/i386/tm-vxworks.h: Ditto.
+       * config/i386/xm-i386v4.h, config/i386/xm-nbsd.h: Ditto.
+       * config/i386/xm-ptx.h, config/i386/xm-ptx4.h: Ditto.
+       * config/i960/tm-vx960.h, config/ia64/nm-aix.h: Ditto.
+       * config/ia64/nm-linux.h, config/ia64/tm-aix.h: Ditto.
+       * config/ia64/tm-linux.h, config/ia64/xm-aix.h: Ditto.
+       * config/m68k/nm-linux.h, config/m68k/nm-m68klynx.h: Ditto.
+       * config/m68k/nm-sysv4.h, config/m68k/tm-linux.h: Ditto.
+       * config/m68k/tm-m68klynx.h, config/m68k/tm-m68kv4.h: Ditto.
+       * config/m68k/tm-sun2os4.h, config/m68k/tm-sun3os4.h: Ditto.
+       * config/m68k/tm-vx68.h, config/m68k/xm-m68kv4.h: Ditto.
+       * config/m68k/xm-nbsd.h, config/m88k/nm-delta88v4.h: Ditto.
+       * config/m88k/tm-delta88v4.h, config/m88k/xm-delta88v4.h: Ditto.
+       * config/mips/nm-irix5.h, config/mips/nm-linux.h: Ditto.
+       * config/mips/tm-linux.h, config/mips/tm-mips64.h: Ditto.
+       * config/mips/tm-mipsm3.h, config/mips/tm-mipsv4.h: Ditto.
+       * config/mips/tm-vxmips.h, config/mips/xm-irix5.h: Ditto.
+       * config/mips/xm-mipsv4.h, config/ns32k/xm-nbsd.h: Ditto.
+       * config/pa/nm-hppao.h, config/powerpc/nm-linux.h: Ditto.
+       * config/powerpc/tm-linux.h, config/powerpc/tm-vxworks.h: Ditto.
+       * config/powerpc/xm-aix.h, config/rs6000/nm-rs6000ly.h: Ditto.
+       * config/rs6000/tm-rs6000ly.h, config/rs6000/xm-aix4.h: Ditto.
+       * config/sh/tm-linux.h, config/sparc/nm-linux.h: Ditto.
+       * config/sparc/nm-sparclynx.h, config/sparc/nm-sun4sol2.h: Ditto.
+       * config/sparc/tm-linux.h, config/sparc/tm-sp64linux.h: Ditto.
+       * config/sparc/tm-sp64sim.h, config/sparc/tm-sparclynx.h: Ditto.
+       * config/sparc/tm-sun4os4.h, config/sparc/tm-sun4sol2.h: Ditto.
+       * config/sparc/tm-vxsparc.h, config/sparc/xm-sun4sol2.h: Ditto.
+
+2002-05-04  Aidan Skinner <aidan@velvet.net>
+
+       * ada-exp.tab.c: New file
+       * ada-exp.y: New file
+       * ada-lang.c: New file
+       * ada-lang.h: New file
+       * ada-lex.c: New file
+       * ada-lex.l: New file
+       * ada-tasks.c: New file
+       * ada-typeprint.c: New file
+       * ada-valprint.c: New file
+       
+2002-06-02  Jason Thorpe  <thorpej@wasabisystems.com>
+
+       * ppcnbsd-tdep.c (ppcnbsd_init_abi): Don't set
+       use_struct_convention to ppc_sysv_abi_broken_use_struct_convention.
+
+2002-06-02  Jason Thorpe  <thorpej@wasabisystems.com>
+
+       * config/rs6000/aix4.mt (TDEPFILES): Use ppc-sysv-tdep.o
+       insetead of ppc-linux-tdep.o.
+       * config/rs6000/rs6000.mt (TDEPFILES): Likewise.
+       * config/rs6000/rs6000lynx.mt (TDEPFILES): Likewise.
+
+2002-06-02  Andrew Cagney  <ac131313@redhat.com>
+
+       2002-05-07 Christian Groessler <chris@groessler.org>
+        * z8k-tdep.c (z8k_print_register_hook): Fix display of 32 and 64
+       bit register contents for little endian hosts.
+
+2002-06-01  Andrew Cagney  <ac131313@redhat.com>
+
+       * MAINTAINERS: Mention that any `HP/UX reader' can be changed by
+       any maintainer.
+
+2002-06-01  Andrew Cagney  <ac131313@redhat.com>
+
+       * gdbarch.h: Regenerate.
+
+2002-06-01  Andrew Cagney  <ac131313@redhat.com>
+
+       * MAINTAINERS: Add everyone to write-after-approval list.
+
+2002-06-01  Andrew Cagney  <ac131313@redhat.com>
+
+       * stack.c (frame_info): Use frame_register_unwind instead of
+       saved_regs.  Mention when the SP is on the stack or in a register.
+
+       * frame.h (frame_register_unwind_ftype): Define.  Document.
+       (struct frame_info): Add field register_unwind and
+       register_unwind_cache.
+       (frame_register_unwind): Declare.
+       (generic_unwind_get_saved_register): Declare.
+
+       * frame.c (frame_register_unwind): New function.
+       (generic_unwind_get_saved_register): New function.
+
+       * blockframe.c (generic_call_dummy_register_unwind): New function.
+       (frame_saved_regs_register_unwind): New function.
+       (set_unwind_by_pc): New function.
+       (create_new_frame): New function.
+       (get_prev_frame): New function.
+
+2002-05-30  Andrew Cagney  <ac131313@redhat.com>
+
+       * a29k-share/: Delete directory.
+       * remote-vx29k.c: Delete file.
+
+2002-05-30  Jason Thorpe  <thorpej@wasabisystems.com>
+
+       * config/djgpp/fnchange.lst: Add ns32knbsd-nat.c, ns32knbsd-tdep.c,
+       ppcnbsd-nat.c, ppcnbsd-tdep.c, sparcnbsd-nat.c, and sparcnbsd-tdep.c.
+
+2002-05-30  Jason Thorpe  <thorpej@wasabisystems.com>
+
+       * Makefile.in (ALLDEPFILES): Add sparc64nbsd-nat.c,
+       sparcnbsd-nat.c, and sparcnbsd-tdep.c.
+       (sparc64nbsd-nat.o)
+       (sparcnbsd-nat.o)
+       (sparcnbsd-tdep.o): New dependency lists.
+       * NEWS: Note new UltraSPARC NetBSD native configuration.
+       * configure.host (sparc64-*-netbsd*): New host.
+       * configure.tgt (sparc-*-netbsdelf*)
+       (sparc-*-netbsd*): Set gdb_target to nbsd.
+       (sparc64-*-netbsd*): New target.
+       * sparc64nbsd-nat.c: New file.
+       * sparcnbsd-nat.c: New file.
+       * sparcnbsd-tdep.c: New file.
+       * sparcnbsd-tdep.h: New file.
+       * config/sparc/nbsd.mt: New file.
+       * config/sparc/nbsd64.mh: New file.
+       * config/sparc/nbsd64.mt: New file.
+       * config/sparc/nbsdaout.mh (NATDEPFILES): Remove corelow.o,
+       sparc-nat.o, and solib.o.  Add sparcnbsd-nat.o.
+       (HOST_IPC): Remove.
+       * config/sparc/nbsdaout.mt: Remove.
+       * config/sparc/nbsdelf.mh (NATDEPFILES): Remove corelow.o,
+       sparc-nat.o, and solib.o.  Add sparcnbsd-nat.o.
+       (HOST_IPC): Remove.
+       * config/sparc/nbsdelf.mt: Remove.
+       * config/sparc/nm-nbsd.h: Update copyright years.  Remove all
+       sparc-nat.c compatiblity defines.
+       * config/sparc/tm-nbsd.h: Update copyright years.  Include solib.h.
+       (GDB_MULTI_ARCH): Set to GDB_MULTI_ARCH_PARTIAL.
+       * config/sparc/tm-nbsd64.h: New file.
+       * config/sparc/tm-nbsdaout.h: Remove.
+       * config/sparc/xm-nbsd.h: Remove.
+
+2002-05-30  Jason Thorpe  <thorpej@wasabisystems.com>
+
+       * Makefile.in (sparc-tdep.o): Add osabi.h to dependency list.
+       * sparc-tdep.c: Include osabi.h.
+       (gdbarch_tdep): Add osabi member.
+       (_initialize_sparc_tdep): Use gdbarch_register.
+       (sparc_gdbarch_init): Use generic OS ABI framework.
+       (sparc_dump_tdep): New function.
+
+2002-05-30  Kevin Buettner  <kevinb@redhat.com>
+
+       * corefile.c (do_captured_read_memory_integer): Return non-zero
+       result.
+       (safe_read_memory_integer): Copy result of memory read when
+       status is non-zero.  Also, add comments.
+
+2002-05-20  Jason Thorpe  <thorpej@wasabisystems.com>
+
+       * Makefile.in (ppc_tdep_h): Define.
+       (ppc-linux-nat.o)
+       (ppc-linux-tdep.o)
+       (rs6000-tdep.o): Use $(ppc_tdep_h).
+       (ppc-sysv-tdep.o)
+       (ppcnbsd-nat.o)
+       (ppcnbsd-tdep.o): New dependency lists.
+       * ppc-tdep.h: Use generic OS ABI framework.
+       * ppc-linux-tdep.c (_initialize_ppc_linux_tdep)
+       (ppc_linux_init_abi): New functions.
+       (ppc_sysv_abi_broken_use_struct_convention)
+       (ppc_sysv_abi_use_struct_convention)
+       (ppc_sysv_abi_push_arguments): Move to...
+       * ppc-sysv-tdep.c: ...here.
+       * ppcnbsd-nat.c: Don't include gdbcore.h and regcache.h.
+       * rs6000-tdep.c (process_note_abi_tag_sections)
+       (get_elfosabi): Remove.
+       (rs6000_gdbarch_init): Use generic OS ABI framework.
+       (rs6000_dump_tdep): New function.
+       (_initialize_rs6000_tdep): Use gdbarch_register.
+       * config/powerpc/linux.mt (TDEPFILES): Add ppc-sysv-tdep.o.
+       * config/powerpc/nbsd.mh (NATDEPFILES): Remove solib-legacy.o.
+       * config/powerpc/aix.mt (TDEPFILES): Use ppc-sysv-tdep.o instead
+       of ppc-linux-tdep.o.
+       * config/powerpc/nbsd.mt (TDEPFILES): Likewise.
+       * config/powerpc/ppc-eabi.mt (TDEPFILES): Likewise.
+       * config/powerpc/ppc-sim.mt (TDEPFILES): Likewise.
+       * config/powerpc/ppcle-eabi.mt (TDEPFILES): Likewise.
+       * config/powerpc/ppcle-sim.mt (TDEPFILES): Likewise.
+       * config/powerpc/vxworks.mt (TDEPFILES): Likewise.
+
+2002-05-29  Jim Blandy  <jimb@redhat.com>
+
+       * macroscope.c (default_macro_scope): Put `void' in empty argument
+       list.
+
+2002-05-29  Andrew Cagney  <ac131313@redhat.com>
+
+       * Makefile.in (arch-utils.o): Add $(sim_regno_h).
+       * arch-utils.c: Include "sim-regno.h".
+       * gdbarch.sh: Don't include "sim-regno.h".
+       * gdbarch.h, gdbarch.c: Regenerate.
+       * sim-regno.h (legacy_register_sim_regno): Move declaration from
+       here.
+       * arch-utils.h (legacy_register_sim_regno): To here.
+       * remote-sim.c (legacy_register_sim_regno): Move function from
+       here.
+       * arch-utils.c (legacy_register_sim_regno): To here.
+
+2002-05-28  Andrew Cagney  <ac131313@redhat.com>
+
+       * sim-regno.h: New file.
+       * Makefile.in (sim_regno_h): Define.
+       (d10v-tdep.o, remote-sim.o): Add dependency on $(sim_regno_h).
+       * remote-sim.c: Include "sim-regno.h" and "gdb_assert.h".
+       (legacy_register_sim_regno): New function.
+       (one2one_register_sim_regno): New function.
+       (gdbsim_fetch_register): Rewrite.
+       (gdbsim_store_register): Only store a register when
+       REGISTER_SIM_REGNO is valid.
+       * d10v-tdep.c: Include "sim-regno.h".
+       (d10v_ts2_register_sim_regno): Add legacy_regiter_sim_regno check.
+       (d10v_ts3_register_sim_regno): Ditto.
+       * gdbarch.sh: Include "sim-regno.h".
+       (REGISTER_SIM_REGNO): Set default to legacy_register_sim_regno.
+       * gdbarch.h, gdbarch.c: Regenerate.
+       * arch-utils.h (default_register_sim_regno): Delete declaration.
+       * arch-utils.c (default_register_sim_regno): Delete function.
+
+2002-05-28  Jason Thorpe  <thorpej@wasabisystems.com>
+
+       * ppcnbsd-nat.c: Rewrite.
+       * ppcnbsd-tdep.c: New file.
+       * ppcnbsd-tdep.h: New file.
+       * config/powerpc/nbsd.mh (NATDEPFILES): Remove corelow.o,
+       solib.o, and solib-svr4.o.
+       * config/powerpc/nbsd.mt (TDEPFILES): Add ppcnbsd-tdep.o,
+       nbsd-tdep.o, and corelow.o.
+
+2002-05-28  Andrew Cagney  <ac131313@redhat.com>
+
+       * MAINTAINERS (--enable-gdb-build-warnings): Rewrite script to use
+       `tr' and `sed'.  Mention that `broken' targets are not expected to
+       build.
+
+2002-05-27  Michal Ludvig  <mludvig@suse.cz>
+
+       * x86-64-tdep.c (x86_64_skip_prologue): Remove obsolete note.
+       Let PC point right after the prologue before looking up symbols.
+       
+2002-05-27  Martin M. Hunt  <hunt@redhat.com>
+
+       * i386-tdep.c (i386_register_virtual_type): Return 
+       builtin_type_vec128i for SSE registers.
+
+       * gdbtypes.h (builtin_type_vec128i): Declare.
+
+       * gdbtypes.c (build_builtin_type_vec128i): New function.
+       (builtin_type_v2_double, builtin_type_v4_int64): New types.
+       (builtin_type_vec128i): New type for SSE2 128-bit registers.
+       (build_gdbtypes): Initialize new builtin vector types.
+       (_initialize_gdbtypes): Register new vector types with gdbarch.
+
+2002-05-26  Jason Thorpe  <thorpej@wasabisystems.com>
+
+       * MAINTAINERS: ns32k is not longer an obsolete candidate,
+       since it has been multi-arch'd.
+       * NEWS: Note that ns32k-*-* is now partial multi-arch.
+       Move Alpha and VAX multi-arch news entries to same section
+       as other multi-arch news.
+
+2002-05-26  Jason Thorpe  <thorpej@wasabisystems.com>
+
+       * ns32k-tdep.c: include gdbtypes.h, inferior.h, regcache.h,
+       target.s, arch-utils.h, ns32k-tdep.h.  Make many functions
+       static.  Rename some register numbers to put them in ns32k-tdep
+       private namespace.
+       (ns32k_get_saved_register, ns32k_gdbarch_init_32082,
+       ns32k_gdbarch_init_32382, ns32k_gdbarch_init, ns32k_dump_tdep): New
+       functions.
+       (_initialize_ns32k_tdep): Use gdbarch_register.
+       * ns32k-tdep.h: New file.
+       * ns32knbsd-tdep.c: New file.
+       * config/ns32k/nbsdaout.mt (TDEPFILES): Add ns32knbsd-tdep.o.
+       * config/ns32k/tm-nbsd.h: Include "ns32k/tm-ns32k.h".
+       (IN_SOLIB_CALL_TRAMPOLINE, REGISTER_NAME, NUM_REGS,
+       REGISTER_BYTES, REGISTER_BYTE): Remove.
+       * config/ns32k/tm-ns32k.h: New file.
+       * config/ns32k/tm-umax.h: Remove.
+
+2002-05-26  Jason Thorpe  <thorpej@wasabisystems.com>
+
+       * ns32k-tdep.c (ns32k_saved_pc_after_call,
+       ns32k_store_struct_return, ns32k_extract_return_value,
+       ns32k_store_return_value, ns32k_extract_struct_value_address): New
+       functions.
+       * config/ns32k/tm-umax.h (SAVED_PC_AFTER_CALL): Define as
+       ns32k_saved_pc_after_call.
+       (STORE_STRUCT_RETURN): Define as ns32k_store_struct_return.
+       (EXTRACT_RETURN_VALUE): Define as ns32k_extract_return_value.
+       (STORE_RETURN_VALUE): Define as ns32k_store_return_value.
+       (EXTRACT_STRUCT_VALUE_ADDRESS): Define as
+       ns32k_extract_struct_value_address.
+
+2002-05-26  Jason Thorpe  <thorpej@wasabisystems.com>
+
+       * ns32k-tdep.c (ns32k_call_dummy_words, sizeof_ns32k_call_dummy_words,
+       ns32k_fix_call_dummy): New.
+       * config/ns32k/tm-umax.h (CALL_DUMMY_WORDS): Define as
+       ns32k_call_dummy_words.
+       (SIZEOF_CALL_DUMMY_WORDS): Define as sizeof_ns32k_call_dummy_words.
+       (CALL_DUMMY, CALL_DUMMY_LENGTH, CALL_DUMMY_ADDR,
+       CALL_DUMMY_NARGS): Remove.
+       (FIX_CALL_DUMMY): Define as ns32k_fix_call_dummy.
+
+2002-05-26  Jason Thorpe  <thorpej@wasabisystems.com>
+
+       * ns32k-tdep.c (ns32k_breakpoint_from_pc, ns32k_frame_chain,
+       ns32k_frame_saved_pc, ns32k_frame_args_address,
+       ns32k_frame_locals_address, ns32k_frame_init_saved_regs,
+       ns32k_push_dummy_frame, ns32k_pop_frame): New functions.
+       * config/ns32k/tm-nbsd.h (FRAME_SAVED_PC): Remove.
+       * config/ns32k/tm-umax.h (INNER_THAN): Define as core_addr_lessthan.
+       (BREAKPOINT_FROM_PC): Define as ns32k_breakpoint_from_pc.
+       (BREAKPOINT): Remove..
+       (FRAME_CHAIN): Define as ns32k_frame_chain.
+       (FRAME_SAVED_PC): Define as ns32k_frame_saved_pc.
+       (FRAME_ARGS_ADDRESS): Define as ns32k_frame_args_address.
+       (FRAME_LOCALS_ADDRESS): Define as ns32k_frame_locals_address.
+       (FRAME_FIND_SAVED_REGS): Remove.
+       (FRAME_INIT_SAVED_REGS): Define as ns32k_frame_init_saved_regs.
+       (PUSH_DUMMY_FRAME): Define as ns32k_push_dummy_frame.
+       (POP_FRAME): Define as ns32k_pop_frame.
+
+2002-05-26  Jason Thorpe  <thorpej@wasabisystems.com>
+
+       * ns32k-tdep.c (ns32k_register_byte_32082,
+       ns32k_register_byte_32382, ns32k_register_raw_size,
+       ns32k_register_virtual_size, ns32k_register_virtual_type): New
+       functions.
+       * config/ns32k/tm-nbsd.h (REGISTER_BYTE): Define as
+       ns32k_register_byte_32382.
+       * config/ns32k/tm-umax.h: Update copyright years.
+       (REGISTER_BYTE): Define as ns32k_register_byte_32082.
+       (REGISTER_RAW_SIZE): Define as ns32k_register_raw_size.
+       (REGISTER_VIRTUAL_SIZE): Define as ns32k_register_virtual_size.
+       (REGISTER_VIRTUAL_TYPE): Define as ns32k_register_virtual_type.
+       (ns32k_get_enter_addr): Fix prototype.
+
+2002-05-26  Jason Thorpe  <thorpej@wasabisystems.com>
+
+       * ns32k-tdep.c: Update copyright years.
+       (ns32k_register_name_32082): New function.
+       (ns32k_register_name_32382): Ditto.
+       * config/ns32k/tm-nbsd.h (REGISTER_NAMES): Remove.
+       (REGISTER_NAME): Define as ns32k_register_name_32382.
+       * config/ns32k/tm-umax.h (REGISTER_NAMES): Remove.
+       (REGISTER_NAME): Define as ns32k_register_name_32082.
+
+2002-05-24  Jim Blandy  <jimb@redhat.com>
+
+       * dwarf2read.c (free_line_header): Use xfree, not free.
+
+2002-05-24  Jason Thorpe  <thorpej@wasabisystems.com>
+
+       * config/djgpp/fnchange.lst: Add alphabsd-nat.c,
+       alphabsd-tdep.c, mipsnbsd-nat.c, and mipsnbsd-tdep.c
+
+2002-05-23  Andrew Cagney  <ac131313@redhat.com>
+
+       * PROBLEMS: Mention s390 and FreeBSD 4.4 build problems.
+
+2002-05-23  Andrew Cagney  <ac131313@redhat.com>
+
+       From Ross Alexander at NEC Europe:
+       * config/pa/hpux11w.mh (NATDEPFILES): Add solib.o.
+
+2002-05-23  Michael Snyder  <msnyder@redhat.com>
+
+       * cli/cli-dump.c (restore_command): Use parse_and_eval_long
+       for input, rather than parse_and_eval_address.  
+
+2002-05-23  Andrew Cagney  <ac131313@redhat.com>
+
+       * d10v-tdep.c: Include "gdb/sim-d10v.h" instead of "sim-d10v.h".
+       * Makefile.in (sim_d10v_h): Update definition.
+
+2002-05-24  Andrew Cagney  <cagney@redhat.com>
+
+       * d10v-tdep.c (d10v_gdbarch_init): Revert old code included in
+       change `2002-05-22 Michael Snyder' below.
+       (d10v_push_arguments): Ditto.
+       (d10v_extract_return_value): Ditto.
+
+2002-05-23  Jim Blandy  <jimb@redhat.com>
+
+       * macrotab.c (check_for_redefinition): Don't complain if the new
+       definition is the same as the previous one.  Take more arguments
+       to allow the comparison.
+       (macro_define_object, macro_define_function): Pass more arguments
+       to check_for_redefinition.
+
+2002-05-22  Michael Snyder  <msnyder@redhat.com>
+
+       * d10v-tdep.c: Change a few macros to enums for ease of debugging.
+       (d10v_frame_chain_valid): Add PC_IN_CALL_DUMMY clause.
+       (d10v_frame_saved_pc): Add PC_IN_CALL_DUMMY clause.
+       (d10v_frame_chain): Bail immediately if PC_IN_CALL_DUMMY.
+       Don't bail if return_pc is PC_IN_CALL_DUMMY.
+       Add a temp variable to save a call (and a memory read).
+       (d10v_init_extra_frame_info): Get fi->pc from callee's return_pc
+       if possible (so that PC_IN_CALL_DUMMY will work).
+
+2002-05-22  Corinna Vinschen  <vinschen@redhat.com>
+
+       * MAINTAINERS: Remove status `OBSOLETE' from v850.
+
+2002-05-22  Michal Ludvig  <mludvig@suse.cz>
+
+       * dwarf2cfi.c (frame_state_for): Added safety check for a valid
+       fde->cie_ptr.
+       (dwarf2_build_frame_info): Corrected handling of eh_frame.
+       (dwarf2_build_frame_info): Add offset to fde->initial_location 
+       so that frames of shared libraries are mapped correctly.
+       (execute_stack_op): Change type of 'result' from ULONGEST to
+       CORE_ADDR.
+       
+2002-05-22  Jason Thorpe  <thorpej@wasabisystems.com>
+
+       * config/alpha/tm-nbsd.h: Include solib.h.
+
+2002-05-22  Jason Thorpe  <thorpej@wasabisystems.com>
+
+       * alphanbsd-tdep.c (alphanbsd_sigtramp_offset): Don't make
+       assumptions about the host's byte order.
+
+2002-05-22  Jason Thorpe  <thorpej@wasabisystems.com>
+
+       * Makefile.in (alphanbsd-tdep.o, shnbsd-tdep.o): Add solib-svr4.h
+       to dependency list.
+       * alphanbsd-tdep.c: Include solib-svr4.h.
+       * shnbsd-tdep.c: Ditto.
+
+2002-05-22  Jason Thorpe  <thorpej@wasabisystems.com>
+
+       * Makefile.in (armnbsd-tdep.o): Add solib-svr4.h and
+       nbsd-tdep.h to dependency list.
+       * configure.host (arm*-*-netbsdelf*, arm*-*-netbsd*,
+       i[3456]86-*-netbsdaout*, i[3456]86-*-netbsd*, m68*-*-netbsd*,
+       ns32k-*-netbsd*, sparc-*-netbsdaout*, sparc-*-netbsd*): Use
+       nbsdaout.mh and nbsdelf.mh consistently.
+       * configure.tgt (i[3456]86-*-netbsd*, m68*-*-netbsd*,
+       ns32k-*-netbsd*, sparc-*-netbsdelf*, sparc-*-netbsd*) Use
+       nbsdaout.mt and nbsdelf.mh consistently.
+       * armnbsd-tdep.c: Include nbsd-tdep.h and solib-svr4.h. 
+       (arm_netbsd_elf_init_abi): Use set_solib_svr4_fetch_link_map_offsets
+       to set nbsd_ilp32_solib_svr4_fetch_link_map_offsets.
+       * config/nm-nbsd.h: Garbage-collect SVR4_SHARED_LIBS.  Move
+       a.out shared library stuff from here...
+       * config/nm-nbsdaout.h: ...to here.
+       * config/tm-nbsd.h: Remove.
+       * config/alpha/nm-nbsd.h (SVR4_SHARED_LIBS): Remove.
+       * config/arm/nbsd.mh: Remove.
+       * config/arm/nbsd.mt (TDEPFILES): Remove solib-sunos.o, add
+       nbsd-tdep.o.
+       * config/arm/nbsdaout.mh: New file. 
+       * config/arm/nbsdelf.mh: New file.
+       * config/arm/nm-nbsdaout.h: New file.
+       * config/i386/nbsd.mh: Remove.
+       * config/i386/nbsd.mt: Remove.
+       * config/i386/nbsdaout.mh: New file.
+       * config/i386/nbsdaout.mt: New file.
+       * config/i386/nbsdelf.mh (NAT_FILE): Use nm-nbsd.h.
+       * config/i386/nbsdelf.mt (TM_FILE): Use tm-nbsd.h.
+       * config/i386/nm-nbsd.h (REGISTER_U_ADDR, 
+       i386_register_u_addr): Remove.
+       * config/i386/nm-nbsdaout.h: New file.
+       * config/i386/nm-nbsdelf.h: Remove.
+       * config/i386/tm-nbsd.h: Don't include config/tm-nbsd.h.
+       (USE_STRUCT_CONVENTION): Remove.
+       * config/i386/tm-nbsdaout.h: New file.
+       * config/i386/tm-nbsdelf.h: Remove.
+       * config/m68k/nbsd.mh: Remove.
+       * config/m68k/nbsd.mt: Remove.
+       * config/m68k/nbsdaout.mh: New file.
+       * config/m68k/nbsdaout.mt: New file. 
+       * config/m68k/nm-nbsd.h: Use config/nm-nbsd.h.
+       * config/m68k/nm-nbsdaout.h: New file.
+       * config/m68k/tm-nbsd.h: Don't include config/tm-nbsd.h.
+       (IN_SOLIB_CALL_TRAMPOLINE): Define.
+       * config/ns32k/nbsd.mh: Remove.
+       * config/ns32k/nbsd.mt: Remove. 
+       * config/ns32k/nbsdaout.mh: New file.
+       * config/ns32k/nbsdaout.mt: New file.
+       * config/ns32k/nm-nbsd.h: Include config/nm-nbsd.h. 
+       * config/ns32k/nm-nbsdaout.h: New file.
+       * config/ns32k/tm-nbsd.h: Don't include config/tm-nbsd.h.  
+       (IN_SOLIB_CALL_TRAMPOLINE): Define.
+       * config/powerpc/nm-nbsd.h: Include config/nm-nbsd.h.
+       (SVR4_SHARED_LIBS): Remove.
+       * config/powerpc/tm-nbsd.h: Dont' include config/tm-nbsd.h.
+       * config/sparc/nbsd.mh: Remove.
+       * config/sparc/nbsd.mt: Remove.
+       * config/sparc/nbsdaout.mh: New file.
+       * config/sparc/nbsdaout.mt: New file.
+       * config/sparc/nbsdelf.mh (NAT_FILE): Use nm-nbsd.h.
+       * config/sparc/nbsdelf.mt: New file.
+       * config/sparc/nm-nbsdaout.h: New file.   
+       * config/sparc/nm-nbsdelf.h: Remove.
+       * config/sparc/tm-nbsd.h: Don't include config/tm-nbsd.h.
+       * config/sparc/tm-nbsdaout.h: New file.
+
+2002-05-21  Jason Thorpe  <thorpej@wasabisystems.com>
+
+       * Makefile.in (ALLDEPFILES): Add mipsnbsd-nat.c and
+       mipsnbsd-tdep.c
+       (mipsnbsd-nat.o, mipsnbsd-tdep.o): New dependency lists.
+
+2002-05-21  Jason Thorpe  <thorpej@wasabisystems.com>
+
+       * Makefile.in (ALLDEPFILES): Add shnbsd-tdep.c and
+       shnbsd-nat.c.
+       (shnbsd-tdep.o, shnbsd-nat.o): New dependency lists.
+
+2002-05-21  Jason Thorpe  <thorpej@wasabisystems.com>
+
+       * NEWS: Note new MIPS NetBSD native configuration. 
+       * configure.host (mips*-*-netbsd*): New host. 
+       * configure.tgt (mips*-*-netbsd*): New target. 
+       * mipsnbsd-nat.c: New file.
+       * mipsnbsd-tdep.c: New file.
+       * mipsnbsd-tdep.h: New file.
+       * config/mips/nbsd.mh: New file.
+       * config/mips/nbsd.mt: New file.
+       * config/mips/nm-nbsd.h: New file.
+       * config/mips/tm-nbsd.h: New file.
+
+2002-05-21  Jason Thorpe  <thorpej@wasabisystems.com>
+
+       * Makefile.in (SFILES): Add osabi.c.
+       (COMMON_OBS): Add osabi.o.
+       (osabi.o): New dependency list.
+       * osabi.c: New file.
+       * osabi.h: New file.
+       * doc/gdbint.texinfo: Document new generic OS ABI framework.
+
+       * Makefile.in (alpha_tdep_h): Define and use instead of
+       alpha-tdep.h.
+       * alpha-tdep.c (alpha_abi_names, process_note_abi_tag_sections,
+       get_elfosabi, alpha_abi_handler_list, alpha_gdbarch_register_os_abi):
+       Remove.
+       (alpha_gdbarch_init, alpha_dump_tdep): Use generic OS ABI framework.
+       * alpha-tdep.h: Include osabi.h.
+       (alpha_abi): Remove.
+       (gdbarch_tdep): Use generic OS ABI framework.
+       * alpha-linux-tdep.c (_initialize_alpha_linux_tdep): Use
+       gdbarch_register_osabi.
+       * alpha-osf1-tdep.c (_initialize_alpha_osf1_tdep): Likewise.
+       * alphafbsd-tdep.c (_initialize_alphafbsd_tdep): Likewise.
+       * alphanbsd-tdep.c (_initialize_alphanbsd_tdep): Likewise.
+
+       * Makefile.in (sh_tdep_h): Add osabi.h.
+       * sh-tdep.h (sh_osabi): Remove.
+       (gdbarch_tdep): Use generic OS ABI framework.
+       * sh-tdep.c (sh_osabi_names, process_note_abi_tag_sections,
+       sh_osabi_handler_list, sh_gdbarch_register_os_abi): Remove.
+       (sh_gdbarch_init, sh_dump_tdep): Use generic OS ABI framework.
+       * shnbsd-tdep.c (_initialize_shnbsd_tdep): Use gdbarch_register_osabi.
+
+       * Makefile.in (arm_tdep_h): Define and use instead of arm-tdep.h.
+       * arm-linux-tdep.c (_initialize_arm_linux_tdep): Use
+       gdbarch_register_osabi.
+       * arm-tdep.c (arm_abi_names, process_note_abi_tag_sections,
+       arm_abi_handler_list, arm_gdbarch_register_os_abi): Remove.
+       (get_elfosabi): Rename to...
+       (arm_elf_osabi_sniffer): ...this.  Adjust to use generic OS
+       ABI framework support routines.
+       (arm_gdbarch_init): Use generic OS ABI framework.
+       (arm_dump_tdep): Likewise.
+       (_initialize_arm_tdep): Likewise.
+       * arm-tdep.h: Include osabi.h.
+       (arm_abi): Remove.
+       (gdbarch_tdep): Remove arm_abi and abi_name members.  Add
+       osabi member.
+       (arm_gdbarch_register_os_abi): Remove prototype.
+       * armnbsd-tdep.c (arm_netbsd_aout_osabi_sniffer): New function.
+       (_initialize_arm_netbsd_tdep): Use gdbarch_register_osabi.
+
+       * Makefile.in (mips-tdep.o): Add osabi.h to dependency list.
+       * mips-tdep.c: Include osabi.h.
+       (gdbarch_tdep, mips_gdbarch_init, mips_dump_tdep): Use generic
+       OS ABI framework.
+
+2002-05-20  Kazu Hirata  <kazu@cs.umass.edu>
+
+       * h8300-tdep.c: Fix formatting.
+
+2002-05-20  Elena Zannoni  <ezannoni@redhat.com>
+
+       * rs6000-tdep.c (rs6000_do_registers_info): Simplify code for
+       printing vector registers.
+
+2002-05-19  Andrew Cagney  <ac131313@redhat.com>
+
+       From Fernando Nasser:
+       * remote.c (remote_async_open_1): Re-throw the exception when the
+       connection fails.
+       (remote_cisco_open): Ditto.
+       (remote_open_1): Ditto.
+
+2002-05-19  Andrew Cagney  <ac131313@redhat.com>
+
+       * remote.c (remote_start_remote_dummy): Add uiout parameter.
+       (remote_start_remote): Add uiout parameter.  Pass through to
+       remote_start_remote_dummy.
+       (remote_open_1): Use catch_exception instead of catch_errors.
+       (remote_async_open_1): Ditto.
+       (remote_cisco_open): Ditto.
+
+2002-05-19  Andrew Cagney  <ac131313@redhat.com>
+
+       * remote.c (remote_start_remote): Replace PTR with void pointer.
+       (sigint_remote_twice_token, sigint_remote_token): Ditto.  Make
+       static.
+
+2002-05-18  Andrew Cagney  <ac131313@redhat.com>
+
+       * gdb_indent.sh: Allow the script to be run in the sim directory.
+
+2002-05-18  Mark Kettenis  <kettenis@gnu.org>
+
+       * config/i386/nm-cygwin.h (NO_PTRACE_H): Remove define.
+       * config/i386/nm-go32.h (NO_PTRACE_H): Remove define.
+
+       * corelow.c (core_open): Only call set_gdbarch_from_file if
+       exec_bfd is NULL.
+
+2002-05-17  Andrey Volkov <avolkov@transas.com>
+
+       * h8300-tdep.c: Add support of EXR register
+       * config/h8300/tm-h8300.h: Ditto. 
+       
+2002-05-17  Andrey Volkov <avolkov@transas.com>
+
+       * h8300-tdep.c: Add additional CCR flags (I,UI,H,U) 
+       
+2002-05-17  Andrey Volkov <avolkov@transas.com>
+
+       * h8300-tdep.c: Change literal regnums to REGNO.
+       
+2002-05-17  Jim Blandy  <jimb@redhat.com>
+
+       * NEWS: Note addition of macro support.
+
+       Expand preprocessor macros in C expressions.
+       * c-lang.h: #include "macroexp.h", for macro_lookup_ftype.
+       (scan_macro_expansion, scanning_macro_expansion,
+       finished_macro_expansion): New function declarations.
+       (expression_macro_lookup_func, expression_macro_lookup_baton): New
+       variable declarations.
+       * parser-defs.h (expression_context_pc): New declaration.
+       * parse.c (expression_context_pc): New variable.
+       (parse_exp_1): Set expression_context_pc, as well as
+       expression_context_block.
+       * c-exp.y (yylex): If we're not already reading the result of a
+       macro expansion, try to macro-expand the next token.  When we're
+       done scanning a macro expansion, switch back to the mainline text.
+       Commas and `if's in a macro's expansion don't terminate the input.
+       * c-lang.c: #include "macroscope.h" and "gdb_assert.h".
+       (macro_original_text, macro_expanded_text,
+       expression_macro_lookup_func, expression_macro_lookup_baton): New
+       variables.
+       (scan_macro_expansion, scanning_macro_expansion,
+       finished_macro_expansion, scan_macro_cleanup, null_macro_lookup,
+       c_preprocess_and_parse): New functions.
+       (c_language_defn, cplus_language_defn, asm_language_defn): Call
+       c_preprocess_and_parse, instead of c_parse.
+       * Makefile.in (c_lang_h): Note that this #includes macroexp.h.
+       (c-lang.o): Note dependency on macroscope.h and gdb_assert.h.
+
+Fri May 17 14:26:19 2002  J"orn Rennecke <joern.rennecke@superh.com>
+
+       * sh-tdep.c (gdb_print_insn_sh64): Delete.
+       (gdb_print_insn_sh): Just set info->endian and use print_insn_sh.
+       (sh_gdbarch_init): Always use gdb_print_insn_sh.
+
+2002-05-17  Corinna Vinschen  <vinschen@redhat.com>
+
+       * NEWS: Add section for multi-arched targets.  Add v850 to that section.
+
+2002-05-17  Jason Thorpe  <thorpej@wasabisystems.com>
+
+       * Makefile.in (sh_tdep_h): Define and use.
+       * config/sh/tm-sh.h (sh_osabi, sh_abi, gdbarch_tdep,
+       register enum): Move to...
+       * * sh-tdep.h: ...here.
+       * sh-tdep.c: Include sh-tdep.h.
+       * sh3-rom.c: Likewise.
+       * shnbsd-tdep.c: Likewise.
+
+2002-05-16  Michael Snyder  <msnyder@redhat.com>
+
+       * arm-tdep.c: Spelling fix in comment.
+
+2002-05-16  Jim Blandy  <jimb@redhat.com>
+
+       Add commands for manually expanding macros and showing their
+       definitions.
+       * macrocmd.c, macroscope.c, macroscope.h: New files.
+       * Makefile.in (SFILES): Add macrocmd.c, macroscope.c.
+       (macroscope_h): New variable.
+       (HFILES_NO_SRCDIR): Add macroscope.h.
+       (COMMON_OBS): Add macrocmd.o, macroscope.o.
+       (macroscope.o, macrocmd.o): New rules.
+
+       Teach the Dwarf 2 reader to read macro information.
+       * dwarf2read.c: #include "macrotab.h".
+       (dwarf_macinfo_buffer): New variable.
+       (struct dwarf2_pinfo): New members: dwarf_macinfo_buffer, and
+       dwarf_macinfo_size.
+       (DWARF_MACINFO_BUFFER, DWARF_MACINFO_SIZE): New macros.
+       (dwarf2_missing_macinfo_section, dwarf2_macros_too_long,
+       dwarf2_macros_not_terminated, dwarf2_macro_outside_file,
+       dwarf2_macro_unmatched_end_file, dwarf2_macro_malformed_definition,
+       dwarf2_macro_spaces_in_definition): New complaints.
+       (dwarf2_has_info): Initialize dwarf_macinfo_offset.
+       (dwarf2_build_psymtabs): Read the .dwarf_macinfo section.
+       (dwarf2_build_psymtabs_hard): Record the buffer and its size in
+       the partial symbol table.
+       (psymtab_to_symtab_1): Set the macinfo buffer and size globals
+       from what's recorded in the partial symbol table.
+       (read_file_scope): If the compilation unit has a
+       `DW_AT_macro_info' attribute, read its macro information.
+       * Makefile.in (dwarf2read.o): Depend on macrotab.h.
+
+2002-05-16  Daniel Jacobowitz  <drow@mvista.com>
+
+       Fix PR gdb/546
+       * ser-tcp.c: Don't include <netinet/udp.h>.
+
+2002-05-16  Stephane Carrez  <stcarrez@nerim.fr>
+
+       * MAINTAINERS: Update my email address.
+
+2002-05-16  Richard Earnshaw  <rearnsha@arm.com>
+
+       * config/arm/nm-nbsd.h: Use "config/nm-nbsd.h" to include generic
+       include file of the same name.
+
+2002-05-16  Corinna Vinschen  <vinschen@redhat.com>
+
+       * configure.tgt: Mark v850 as multi-arched.
+       * config/v850/tm-v850.h: Remove file.
+       * config/v850/v850.mt: Eliminate TM_FILE.
+
+2002-05-16  Corinna Vinschen  <vinschen@redhat.com>
+
+       * v850-tdep.c: Full multi-arch.
+       * config/v850/tm-v850.h: Eliminate or move to v850-tdep.c everything.
+       Define GDB_MULTI_ARCH to 2.
+
+2002-05-16  Pierre Muller  <muller@ics.u-strasbg.fr>
+
+       * p-exp.y (current_type): New static variable.
+       Carries the type of the expression at the position that is parsed.
+       (push_current_type, pop_current_type): Two new functions. Used
+       to store/restore current_type in expression on specific tokens.
+       (search_field): New static variable. Set to one after parsing a point
+       as at that point only a FIELDNAME token should be searched.
+       (FIELDNAME): New token. After a point only a token belonging to 
+       current_type type definition is allowed.
+       (all over token rules): reset and change current_type according
+       to rules.
+       (exp '[' rule): insert implicit array index field if
+       exp is a pascal string type.
+
+2002-05-16  Corinna Vinschen  <vinschen@redhat.com>
+
+       * v850-tdep.c: Fix comment for v850_scan_prologue.  Remove extra
+       frame info.  Use frame_info's saved_regs instead of matching member
+       in extra_frame_info throughout.
+       (v850_frame_init_saved_regs): New function.
+       (v850_init_extra_frame_info): Move most functionality into
+       v850_frame_init_saved_regs().
+       * config/v850/tm-v850.h (EXTRA_FRAME_INFO): Remove definition.
+       (v850_frame_find_saved_regs): Remove declaration.
+       (FRAME_FIND_SAVED_REGS): Remove definition.
+       (v850_frame_init_saved_regs): Add declaration.
+       (FRAME_INIT_SAVED_REGS): Add definition.
+
+2002-05-16  Corinna Vinschen  <vinschen@redhat.com>
+
+       * v850-tdep.c: Begin multi-arch'ing v850.
+       (v850_target_architecture_hook): Remove function.
+       (v850_gdbarch_init): New function.  Add code previously in
+       v850_target_architecture_hook().
+       (_initialize_v850_tdep): Don't  set target_architecture_hook.
+       Call register_gdbarch_init() instead.
+
+2002-05-16 Daniel Jacobowitz  <drow@mvista.com>
+
+       * gdbtypes.h (struct cplus_struct_type): Remove args field.
+       * hpread.c (hpread_read_struct_type): Remove assignments to args.
+       (fixup_class_method_type): Likewise.
+
+2002-05-15  Jim Blandy  <jimb@redhat.com>
+
+       Add macro structures to GDB's symbol tables.  Nobody puts anything
+       in them yet.
+       * symtab.h (struct symtab): New member: `macro_table'.
+       * buildsym.h (pending_macros): New global variable.
+       * buildsym.c: #include "macrotab.h".
+       (buildsym_init): Initialize `pending_macros'.
+       (end_symtab): If we found macro information while reading a CU's
+       debugging info, do build a symtab structure for it.  Make the
+       symtab point to the macro information, and clear the
+       `pending_macros' pointer which held it while we were reading the
+       debug info.
+       (really_free_pendings): Free any pending macro table.
+       * objfiles.h (struct objfile): New member: `macro_cache'.
+       * objfiles.c (allocate_objfile): Set allocate and free functions
+       for the macro cache's objstack.
+       (free_objfile): Empty the macro cache's obstack.
+       * symfile.c (reread_symbols): Empty the macro cache's obstack, and
+       set new allocate and free functions for it.
+       * solib-sunos.c (allocate_rt_common_objfile): Set allocate and
+       free functions for the macro cache's objstack.  (Why is this
+       function building its own objfile?)
+       * symmisc.c (print_objfile_statistics): Print statistics on the
+       macro bcache.
+       * Makefile.in: Note that buildsym.o depends on macrotab.h.
+
+2002-05-15  Richard Earnshaw  <rearnsha@arm.com>
+
+       * config/arm/nm-nbsd.h: Use <> for include of config/nm-nbsd.h.
+       (REGISTER_U_ADDR): Delete definition.
+       (arm_register_u_addr): Delete declaration.
+
+2002-05-15  Richard Earnshaw  <rearnsha@arm.com>
+
+       * arm-linux-tdep.c (ARM_LINUX_JB_PC): Renamed from JB_PC.
+       (ARM_LINUX_JB_ELEMENT_SIZE): Likewise.
+
+2002-05-14  Andrew Cagney  <ac131313@redhat.com>
+
+       * regcache.c (register_valid): Revise comments refering to "Not
+       available" and "unavailable".
+       * frame.c (frame_register_read): Ditto.
+       * findvar.c (value_of_register): Ditto.
+
+2002-05-15  Andrew Cagney  <cagney@redhat.com>
+
+       * Makefile.in (remote_sim_h): Replace remote-sim_h.
+       (remote-sim.o): Update dependencies.
+       (d10v-tdep.o): Specify dependencies.
+       (sim_d10v_h): Define.
+
+2002-05-14  Jim Blandy  <jimb@redhat.com>
+
+       * macroexp.c (init_buffer, gather_arguments, expand): Use NULL, not 0.
+       * macrotab.c (macro_lookup_inclusion, find_definition,
+       new_macro_table): Same.
+       
+       * macroexp.c (currently_rescanning, expand): Use `strcmp () == 0',
+       not `! strcmp ()'.  This is a dubious improvement.
+       * macrotab.c (macro_lookup_inclusion, find_definition): Same.
+
+       * macrotab.c (macro_lookup_inclusion): Initialize `best_depth',
+       although it's not necessary, to avoid a warning.
+
+2002-05-14  Daniel Jacobowitz  <drow@mvista.com>
+
+       * gdbtypes.h: Update accessor macros to use TYPE_MAIN_TYPE.
+       (TYPE_CONST, TYPE_VOLATILE, TYPE_CODE_SPACE, TYPE_DATA_SPACE): Use
+       TYPE_INSTANCE_FLAGS.
+       (struct main_type): New.
+       (struct type): Move most members to struct main_type.  Change
+       cv_type and as_type to new type_chain member.  Add instance_flags.
+       (TYPE_MAIN_TYPE, TYPE_CHAIN, TYPE_INSTANCE_FLAGS): New macros.
+       (TYPE_CV_TYPE, TYPE_AS_TYPE): Remove.
+       (finish_cv_type): Remove prototype.
+       * gdbtypes.c (alloc_type): Update comment.  Allocate TYPE_MAIN_TYPE.
+       Set TYPE_CHAIN.
+       (alloc_type_instance): New function.
+       (smash_type): New function.
+       (make_pointer_type, make_reference_type, make_function_type)
+       (smash_to_member_type, smash_to_method_type): Call smash_type.
+       (make_qualified_type): New function.
+       (make_type_with_address_space): Call make_qualified_type.
+       (make_cv_type): Likewise.
+       (finish_cv_type): Remove unnecessary function.
+       (replace_type): Update comment.  Copy TYPE_MAIN_TYPE.
+       (recursive_dump_type): Dump TYPE_CHAIN and TYPE_INSTANCE_FLAGS;
+       remove TYPE_CV_TYPE and TYPE_AS_TYPE.
+       * c-typeprint.c (c_type_print_modifier): Use TYPE_INSTANCE_FLAGS.
+       * dwarf2read.c (read_structure_scope): Don't call finish_cv_type.
+       * hpread.c (hpread_read_struct_type): Likewise.
+       * stabsread.c (read_struct_type): Likewise.
+
+2002-05-14  Elena Zannoni  <ezannoni@redhat.com>
+
+       * configure.tgt: Add a catch all sh* target, for cases like
+       sh[2,3,4]-elf and sh-hms.
+
+2002-05-14  Keith Seitz  <keiths@redhat.com>
+
+       * event-loop.c (create_file_handler): Don't do anything but
+       update data when we are given a fd which we are already
+       monitoring.
+
+2002-05-14  Michal Ludvig  <mludvig@suse.cz>
+
+       * dwarf2cfi.c (context_cpy): Copy registers correctly.
+       (update_context): Use __func__ in warnings.
+       
+2002-05-14  Daniel Jacobowitz  <drow@mvista.com>
+
+       * ser-tcp.c: Include <netinet/udp.h>.  Rename tcp_open
+       and tcp_close to net_open and net_close.
+       (net_open): Accept "udp:" and "tcp:" specifications.  Connect
+       using UDP if requested.  Don't try to disable Nagle on UDP
+       sockets.
+       * remote.c (remote_serial_open): New function.  Warn about UDP.
+       (remote_open_1, remote_async_open_1, remote_cisco_open): Call it.
+
+2002-05-13  Elena Zannoni  <ezannoni@redhat.com>
+
+       * MAINTAINERS: List sh-elf as buildable with ,-Werror.
+
+2002-05-13  Elena Zannoni  <ezannoni@redhat.com>
+
+       * configure.tgt: Remove sh-hms target.
+       * MAINTAINERS: Don't list sh-hms as a separate target.
+
+2002-05-13  Jim Blandy  <jimb@redhat.com>
+
+       Add first preprocessor macro-expansion files.
+       * macroexp.c, macroexp.h, macrotab.c, macrotab.h: New files.
+       * Makefile.in (SFILES): Add macrotab.c, macroexp.c.
+       (splay_tree_h, macroexp_h, macrotab_h): New variable.
+       (HFILES_NO_SRCDIR): Add macrotab.h, macroexp.h.
+       (COMMON_OBS): Add macrotab.o, macroexp.o.
+       (macroexp.o, macrotab.o): New rules.
+
+2002-05-13  Andrew Cagney  <ac131313@redhat.com>
+
+       * config/m88k/tm-m88k.h: Update copyright.
+       (m88k_target_write_pc): Declare
+       (TARGET_WRITE_PC): Redefine using m88k_target_write_pc.
+       (M88K_NNPC_REGNUM): Rename NNPC_REGNUM.
+       (SHIFT_INST_REGS): Update definition.
+       * m88k-tdep.c (m88k_target_write_pc): New function.  Implement
+       using old definition of TARGET_WRITE_PC.
+       * regcache.c (generic_target_write_pc): Delete code handling
+       NNPC_REGNUM.
+       * gdbarch.sh (NNPC_REGNUM): Delete.
+       * gdbarch.h, gdbarch.c: Regenerate.
+
+2002-05-13  Richard Earnshaw  <rearnsha@arm.com>
+
+       * builtin-regs.c (value_of_builtin_reg): Correctly calculate the
+       builtin reg number.
+
+2002-05-13  Daniel Jacobowitz  <drow@mvista.com>
+
+       * ax-gdb.c (gen_sign_extend, gen_fetch, gen_usual_unary)
+       (gen_cast, gen_scale, gen_add, gen_sub, gen_binop, gen_deref)
+       (gen_address_of, gen_struct_ref, gen_repeat): Use type
+       access macros.
+       * c-typeprint.c (cp_type_print_method_args): Likewise.
+       (c_type_print_args): Likewise.
+       * d10v-tdep.c (d10v_push_arguments): Likewise.
+       (d10v_extract_return_value): Likewise.
+       * expprint.c (print_subexp): Likewise.
+       * gdbtypes.c (lookup_primitive_typename): Likewise.
+       (lookup_template_type, add_mangled_type, print_arg_types): Likewise.
+       * gdbtypes.h (TYPE_UNSIGNED, TYPE_NOSIGN, TYPE_STUB)
+       (TYPE_TARGET_STUB, TYPE_STATIC, TYPE_CONST, TYPE_VOLATILE)
+       (TYPE_PROTOTYPED, TYPE_INCOMPLETE, TYPE_CODE_SPACE, TYPE_VARARGS)
+       (TYPE_VECTOR): Likewise.
+       * hpread.c (hpread_read_struct_type)
+       (fix_static_member_physnames, fixup_class_method_type)
+       (hpread_type_lookup): Likewise.
+       * mdebugread.c (parse_symbol, parse_type): Likewise.
+       * p-lang.c (is_pascal_string_type): Likewise.
+       * valops.c (hand_function_call): Likewise.
+       * x86-64-tdep.c (classify_argument): Likewise.
+
+       * hpread.c (hpread_read_function_type)
+       (hpread_read_doc_function_type): Call replace_type.
+       * dstread.c (create_new_type): Delete.
+       (decode_dst_structure, process_dst_function): Call alloc_type.
+       Use type access macros.
+
+2002-05-12  Mark Kettenis  <kettenis@gnu.org>
+
+       * i387-tdep.c (i387_supply_fxsave): Skip the SSE registers if
+       the're not supported by the current architecture.
+       (i387_fill_fxsave): Likewise.
+
+2002-05-12  Fred Fish  <fnf@redhat.com>
+
+       * symfile.c (default_symfile_offsets): Arrange for uninitialized
+       sect_index_xxx members to index the first slot in section_offsets
+       if all of the section_offsets are zero.
+
+2002-05-12  Mark Kettenis  <kettenis@gnu.org>
+
+       * configure.tgt (sparc-*openbsd): Remove entry accidentially
+       checked in with last change.
+
+2002-05-12  Mark Kettenis  <kettenis@gnu.org>
+
+       * configure.tgt (i[3456]86-*-unixware*, i[3456]86-*-unixware2*):
+       Remove targets.  These are canonicalized to i386-*-sysv4.2uw by
+       config.sub.
+
+2002-05-12  Daniel Jacobowitz  <drow@mvista.com>
+
+       * Makefile.in: Update dependencies.
+
+2002-05-11  Andrew Cagney  <ac131313@redhat.com>
+
+       * language.c (local_hex_string_custom): Simplify.  Do not depend
+       on PRINTF_HAS_LONG_LONG or CC_HAS_LONG_LONG.
+
+       * memattr.c (mem_info_command): Replace calls to
+       longest_local_hex_string and longest_local_hex_string_custom.
+       * buildsym.c (make_blockvector): Ditto.
+       * solib.c (info_sharedlibrary_command): Ditto.
+       * tracepoint.c (tracepoints_info): Ditto.
+       * symtab.c (print_msymbol_info): Ditto.
+
+       * language.c (local_hex_string): Delete.
+       (local_hex_string_custom): Delete.
+       (longest_local_hex_string): Rename to local_hex_string.
+       (longest_local_hex_string_custom): Rename to
+       local_hex_string_custom.
+       * language.h (local_hex_string): Change parameter type to LONGEST.
+       (local_hex_string_custom): Ditto.
+       (longest_local_hex_string): Delete declaration.
+       (longest_local_hex_string_custom): Ditto.
+
+       * solib.c: Update copyright.
+       * memattr.c: Update copyright.
+       
+2002-05-11  Andrew Cagney  <ac131313@redhat.com>
+
+       * arch-utils.h (legacy_register_to_value): Declare.
+       (legacy_value_to_register): Declare.
+       (legacy_convert_register_p): Declare.
+       * arch-utils.c (legacy_register_to_value): New function.
+       (legacy_value_to_register): New function.
+       (legacy_convert_register_p): New function.
+
+       * gdbarch.sh (REGISTER_TO_VALUE): Define.
+       (VALUE_TO_REGISTER): Define.
+       (CONVERT_REGISTER_P): Define.
+       * gdbarch.h, gdbarch.c: Regenerate.
+
+       * valops.c (value_assign): Use CONVERT_REGISTER_P and
+       VALUE_TO_REGISTER.
+       * findvar.c (value_from_register): Use REGISTER_TO_VALUE and
+       CONVERT_REGISTER_P.
+
+2005-05-11  Daniel Jacobowitz  <drow@mvista.com>
+           Peter Schauer  <pes@regent.e-technik.tu-muenchen.de>
+
+       * Makefile.in: Update dependencies for valops.c.
+       * valops.c: Include "gdb_assert.h".
+       (typecmp): Skip THIS parameter to methods.
+       (find_method_list): Remove static_memfuncp argument,
+       update callers.  Check for stub methods.
+       (find_value_oload_method_list): Don't set *static_memfuncp.
+       (find_overload_match): Don't check for stub methods.  Assert
+       that methods are not stubbed.  Handle static methods.
+       (value_find_oload_method_list): Remove static_memfuncp argument.
+       * gdbtypes.c (check_stub_method): Do not add THIS pointer
+       to the argument list for static stub methods.
+       * value.h (value_find_oload_method_list): Update prototype.
+
+2002-05-11  Andrew Cagney  <ac131313@redhat.com>
+
+       * arch-utils.h (generic_register_size): Declare.
+       (generic_register_raw_size, generic_register_virtual_size): Delete
+       declarations.
+       * arch-utils.c (generic_register_raw_size): Delete.
+       (generic_register_size): New function.
+       (generic_register_virtual_size): Delete.
+
+       * gdbarch.sh (REGISTER_RAW_SIZE, REGISTER_VIRTUAL_SIZE): Make
+       default generic_register_size.
+       * gdbarch.h, gdbarch.c: Re-generate.
+       
+       * d10v-tdep.c (d10v_gdbarch_init): Use generic_register_size for
+       register_virtual_size.
+       * x86-64-tdep.c (x86_64_gdbarch_init): Ditto.
+       * rs6000-tdep.c (rs6000_gdbarch_init): Ditto.
+
+2002-05-11  Andrew Cagney  <ac131313@redhat.com>
+
+       * gdbarch.sh (gdbarch_data): Add gdbarch parameter.
+       * gdbarch.h, gdbarch.c: Regenerate.
+       * gnu-v3-abi.c: Update copyright.
+       (vtable_address_point_offset): Update.
+       (gnuv3_rtti_type): Update.
+       (gnuv3_baseclass_offset): Update.
+       * solib-svr4.c (svr4_fetch_link_map_offsets): Update.
+       (init_fetch_link_map_offsets): Update.
+       * remote.c (get_remote_state): Update.
+       
+2002-05-11  Daniel Jacobowitz  <drow@mvista.com>
+
+       * TODO: Remove value_headof/value_from_vtable_info comment.
+       * printcmd.c (print_command_1): Don't call value_from_vtable_info.
+       * values.c (value_headof, value_from_vtable_info): Delete.
+       * value.h (value_from_vtable_info): Delete prototype.
+
+2002-05-11  Andrew Cagney  <ac131313@redhat.com>
+
+       * Makefile.in: Replace gdb_assert.h with $(gdb_assert_h),
+       gdb_string.h with $(gdb_string_h) and gdb_regex.h with
+       $(gdb_regex_h).
+       (gdb_assert_h): Define.
+       (gdb_wait_h): Define.
+       (gdb_regex_h): Define.
+
+2002-05-11 Daniel Jacobowitz  <drow@mvista.com>
+
+       From Peter Schauer <Peter.Schauer@Regent.E-Technik.TU-Muenchen.DE>:
+       * linespec.c (find_methods): Handle GCC 3.x template constructors.
+
+2002-05-11  Jason Thorpe  <thorpej@wasabisystems.com>
+
+       * nbsd-tdep.c: Fix comment.
+
+2002-05-11  Jason Thorpe  <thorpej@wasabisystems.com>
+
+       * Makefile.in (ALLDEPFILES): Add nbsd-tdep.c.
+       (alphanbsd-tdep.o): Add nbsd-tdep.h to dependency list.
+       (nbsd-tdep.o): New dependency list.
+       * alphanbsd-tdep.c: Don't include solib-svr4.h.  Include
+       nbsd-tdep.h.
+       (alphanbsd_solib_svr4_fetch_link_map_offsets): Remove.
+       (alphanbsd_init_abi): Use nbsd_lp64_solib_svr4_fetch_link_map_offsets.
+       * nbsd-tdep.c: New file.
+       * nbsd-tdep.h: New file.
+       * shnbsd-tdep.c: Don't include solib-svr4.h.  Include
+       nbsd-tdep.h.
+       (shnbsd_solib_svr4_fetch_link_map_offsets): Remove.
+       (shnbsd_init_abi): Use nbsd_ilp32_solib_svr4_fetch_link_map_offsets.
+       * config/alpha/nbsd.mt (TDEPFILES): Add nbsd-tdep.o.
+       * config/sh/nbsd.mt (TDEPFILES): Ditto.
+
+2002-05-11  Jason Thorpe  <thorpej@wasabisystems.com>
+
+       * config/alpha/nbsd.mh (NATDEPFILES): Remove corelow.o.
+       * config/alpha/nbsd.mt (TDEPFILES): Add corelow.o.
+       * config/i386/nbsd.mh (NATDEPFILES): Remove corelow.o.
+       * config/i386/nbsd.mt (TDEPFILES): Add corelow.o.
+       * config/i386/nbsdelf.mh (NATDEPFILES): Remove corelow.o.
+       * config/i386/nbsdelf.mt (TDEPFILES): Add corelow.o.
+
+2002-05-11  Jason Thorpe  <thorpej@wasabisystems.com>
+
+       * config/i386/nbsd.mh (NATDEPFILES): Use line continuations.
+       * config/i386/nbsdelf.mh (NATDEPFILES): Likewise.
+       * config/m68k/nbsd.mh (NATDEPFILES): Likewise.
+       * config/ns32k/nbsd.mh (NATDEPFILES): Likewise.
+       * config/powerpc/nbsd.mh (NATDEPFILES): Likewise.
+       * config/sparc/nbsd.mh (NATDEPFILES): Likewise.
+       * config/sparc/nbsdelf.mh (NATDEPFILES): Likewise.
+
+2002-05-11  Jason Thorpe  <thorpej@wasabisystems.com>
+
+       * i386nbsd-nat.c: Delete file.  Move fetch_core_registers and
+       fetch_elfcore_registers to...
+       * i386nbsd-tdep.c: ...here.
+       (i386nbsd_use_struct_convention): Rename to...
+       (i386nbsd_aout_use_struct_convention): ...this.
+       (i386nbsd_supply_reg): New function.
+       (i386nbsd_fill_reg): New function.
+       (fetch_core_registers): Use i386nbsd_supply_reg.
+       (fetch_elfcore_registers): Likewise.
+       (_initialize_i386nbsd_tdep): New function.
+       * config/i386/nbsd.mh (NATDEPFILES): Remove i386nbsd-nat.o.
+       * config/i386/nbsdelf.mh (NATDEPFILES): Likewise.
+       * config/i386/nbsdelf.mt (TDEPFILES): Add i386nbsd-tdep.o.
+       * config/i386/tm-nbsd.h (i386nbsd_use_struct_convention): Rename to...
+       (i386nbsd_aout_use_struct_convention): ...this.
+
+2002-05-11  Jason Thorpe  <thorpej@wasabisystems.com>
+
+       * shnbsd-nat.c (fetch_inferior_registers): Use shnbsd_supply_reg.
+       (store_inferior_registers): Use shnbsd_fill_reg.
+       * shnbsd-tdep.c (sh_nbsd_supply_registers, 
+       sh_nbsd_supply_register): Collapse into...
+       (shnbsd_supply_reg): ...this.
+       (sh_nbsd_fill_registers, sh_nbsd_fill_register): Collapse into...
+       (shnbsd_fill_reg): ...this.
+       (sh_nbsd_solib_svr4_fetch_link_map_offsets): Rename to...
+       (shnbsd_solib_svr4_fetch_link_map_offsets): ...this.
+       (fetch_core_registers): Use shnbsd_supply_reg.
+       (fetch_elfcore_registers): Use shnbsd_supply_reg.
+       (sh_nbsd_core_fns): Rename to...
+       (shnbsd_core_fns): ...this.
+       (sh_nbsd_elfcore_fns): Rename to...
+       (shnbsd_elfcore_fns): ...this.
+       (sh_nbsd_init_abi): Rename to...
+       (shnbsd_init_abi): ...this.
+       (_initialize_sh_nbsd_tdep): Rename to...
+       (_initialize_shnbsd_tdep): ...this.
+       * shnbsd-tdep.h (sh_nbsd_supply_registers,
+       sh_nbsd_supply_register, sh_nbsd_fill_registers,
+       sh_nbsd_fill_register): Remove prototypes.
+       (shnbsd_supply_reg, shnbsd_fill_reg): Add prototypes.
+
+2002-05-11  Jason Thorpe  <thorpej@wasabisystems.com>
+
+       * Makefile.in (ALLDEPFILES): Remove i387-nat.c.
+       (i387-nat.o): Delete dependency list.
+       (go32-nat.o): Change i387-nat.h to i387-tdep.h.
+       (x86-64-linux-nat.o): Likewise.
+       * i387-nat.c: Delete file, moving contents to...
+       * i387-tdep.c: ...here.
+       * i387-nat.h: Rename...
+       * i387-tdep.h: ...to this.
+       * go32-nat.c: Include i387-tdep.h instead of i387-nat.h.
+       * i386-linux-nat.c: Likewise.
+       * i386bsd-nat.c: Likewise.
+       * i386gnu-nat.c: Likewise.
+       * i386nbsd-nat.c: Likewise.
+       * i386v4-nat.c: Likewise.
+       * x86-64-linux-nat.c: Likewise.
+       * config/i386/fbsd.mh (NATDEPFILES): Remove i387-nat.o.
+       * config/i386/go32.mh (NATDEPFILES): Likewise.
+       * config/i386/i386gnu.mh (NATDEPFILES): Likewise.
+       * config/i386/i386sol2.mh (NATDEPFILES): Likewise.
+       * config/i386/i386v42mp.mh (NATDEPFILES): Likewise.
+       * config/i386/linux.mh (NATDEPFILES): Likewise.
+       * config/i386/nbsd.mh (NATDEPFILES): Likewise.
+       * config/i386/nbsdelf.mh (NATDEPFILES): Likewise.
+       * config/i386/obsd.mh (NATDEPFILES): Likewise.
+       * config/i386/x86-64linux.mh (NATDEPFILES): Likewise.
+
+2002-05-11  Jason Thorpe  <thorpej@wasabisystems.com>
+
+       * Makefile.in (ALLDEPFILES): Remove alphanbsd-nat.c.
+       (alphanbsd-nat.o): Remove dependency list.
+       (alphanbsd-tdep.o): Add $(regcache_h) to dependency list.
+       * alphanbsd-nat.c: Delete.  Contents moved to...
+       * alphanbsd-tdep.c: ...here.
+       (_initialize_alphanbsd_tdep): Register core functions.
+       * config/alpha/nbsd.mh (NATDEPFILES): Remove alphanbsd-nat.o.
+
+2002-05-11  Jason Thorpe  <thorpej@wasabisystems.com>
+
+       * Makefile.in (ALLDEPFILES): Add alphabsd-tdep.c.
+       (alphabsd-nat.o): Depend on alphabsd-tdep.h.
+       (alphanbsd-nat.o): Likewise.
+       (alphabsd-tdep.o): New dependency list.
+       * alphabsd-nat.c (supply_gregset): Use alphabsd_supply_reg.
+       (fill_gregset): Use alphabsd_fill_reg.
+       (supply_fpregset): Use alphabsd_supply_fpreg.
+       (fill_fpregset): Use alphabsd_fill_fpreg.
+       (fetch_inferior_registers): Use struct reg and struct fpreg
+       rather than gregset_t and fpregset_t.  Use alphabsd_supply_reg
+       and alphabsd_supply_fpreg.
+       (store_inferior_registers): Use struct reg and struct fpreg
+       rather than gregset_t and fpregset_t.  Use alphabsd_fill_reg
+       and alphabsd_fill_fpreg.
+       * alphabsd-tdep.c: New file.
+       * alphabsd-tdep.h: New file.
+       * alphanbsd-nat.c (fetch_core_registers): Use alphabsd_supply_fpreg.
+       (fetch_elfcore_registers): Use alphabsd_supply_reg and
+       alphabsd_supply_fpreg.
+       * config/alpha/fbsd.mt (TDEPFILES): Add alphabsd-tdep.o.
+       * config/alpha/nbsd.mt (TDEPFILES): Likewise.
+
+2002-05-11  Eric Christopher  <echristo@redhat.com>
+
+       * mips-tdep.c (mips_double_register_type): Fix thinko.
+       (mips_single_register_type): Ditto.
+       * MAINTAINERS: Add self.
+
+2002-05-11  Mark Kettenis  <kettenis@gnu.org>
+
+       * i387-nat.c (i387_supply_register, i387_fill_fsave,
+       i387_supply_fxsave, i387_fill_fxsave): Rewrite in order to do the
+       right thing on architectures with different endianness and/or
+       integer sizes.
+
+2002-05-10  Jason Thorpe  <thorpej@wasabisystems.com>
+
+       From Christian Limpach <chris@Pin.LU>
+       * configure.in: Change sed expression which comments out
+       NATDEPFILES to also comment out continuation lines.
+       * configure: Regenerate.
+
+2002-05-10  Elena Zannoni  <ezannoni@redhat.com>
+
+        * sh-tdep.c: Clean up code erroneously reintroduced by previous
+       big patch.
+
+2002-05-10  Elena Zannoni  <ezannoni@redhat.com>
+
+        * sh-tdep.c: Include correct file.
+
+2002-05-10  Elena Zannoni  <ezannoni@redhat.com>
+
+        New support for sh64-elf (sh5) target.
+
+        * configure.tgt: For sh64-elf target, default to sh-elf.
+
+        * config/sh/tm-sh.h (enum sh-abi): Possible ABI's.
+        (struct gdbarch_tdep): Add new fields for new registers and ABI
+        info.
+
+        * sh-tdep.c: Include elf-bfd.h, elf/sh.h, gdb/sim-sh.h.
+        (NUM_PSEUDO_REGS_SH_MEDIA, NUM_PSEUDO_REGS_SH_COMPACT,
+        MSYMBOL_IS_SPECIAL, IS_ISA32_ADDR, MAKE_ISA32_ADDR,
+        UNMAKE_ISA32_ADDR, IS_PTABSL_R18, IS_STS_R0, IS_STS_PR,
+        IS_MOV_TO_R15, IS_MOV_R14, IS_STQ_R18_R14, IS_STQ_R18_R15,
+        IS_STL_R18_R15, IS_STQ_R14_R15, IS_STL_R14_R15, IS_ADDIL_SP_MEDIA,
+        IS_ADDI_SP_MEDIA, IS_ADDL_SP_FP_MEDIA, IS_ADD_SP_FP_MEDIA,
+        IS_MOV_SP_FP_MEDIA, IS_MOV_R0, IS_MOVL_R0, IS_ADD_SP_R0,
+        IS_MOV_R14_R0, IS_MEDIA_IND_ARG_MOV, IS_MEDIA_ARG_MOV,
+        IS_MEDIA_MOV_TO_R14, IS_COMPACT_IND_ARG_MOV, IS_COMPACT_ARG_MOV,
+        IS_COMPACT_MOV_TO_R14, IS_JSR_R0, IS_NOP): New macros.
+        (sh_sh64_register_name, sh64_elf_make_msymbol_special,
+        pc_is_isa32, sh_sh64_breakpoint_from_pc, look_for_args_moves,
+        sh64_skip_prologue_hard_way, sh64_use_struct_convention,
+        gdb_print_insn_sh64, translate_insn_rn, sh64_frame_chain,
+        sh64_get_saved_pr, fpp_reg_base_num, is_media_pseudo,
+        sh64_get_gdb_regnum, sh64_media_reg_base_num,
+        sh64_compact_reg_base_num, translate_rn_to_arch_reg_num,
+        sign_extend, sh64_nofp_frame_init_saved_regs,
+        sh64_init_extra_frame_info, sh64_get_saved_register,
+        sh64_extract_struct_value_address, sh64_pop_frame,
+        sh64_push_arguments, sh64_extract_return_value,
+        sh64_store_return_value, sh64_show_media_regs,
+        sh64_show_compact_regs, sh64_show_regs, sh_sh64_register_byte,
+        sh_sh64_register_raw_size, sh_sh64_register_virtual_size,
+        sh_sh64_register_virtual_type,
+        sh_sh64_register_convert_to_virtual,
+        sh_sh64_register_convert_to_raw, sh64_pseudo_register_read,
+        sh64_register_read, sh64_pseudo_register_write,
+        sh64_register_write, do_fv_c_register_info, do_dr_c_register_info,
+        do_r_c_register_info, do_fpp_register_info, do_cr_c_register_info,
+        sh64_do_pseudo_register, sh_compact_do_registers_info,
+        sh64_do_registers_info, sh_gdbarch_init): New functions.
+
+2002-05-10  Elena Zannoni  <ezannoni@redhat.com>
+
+       * sh-tdep.c (sh_breakpoint_from_pc): Add 'const' to return type.
+
+2002-05-10 Daniel Jacobowitz  <drow@mvista.com>
+
+       * linespec.c (decode_line_1): Check for a double quote after
+       a filename correctly.
+
+2002-05-10  Jim Blandy  <jimb@redhat.com>
+
+       Properly track the size of the current objfile's .debug_line section.
+       * dwarf2read.c (struct dwarf2_pinfo): New member: dwarf_line_size.
+       (DWARF_LINE_SIZE): New macro.
+       (dwarf2_build_psymtabs_hard): Record the line section's size in
+       the partial symbol table.
+       (psymtab_to_symtab_1): Restore dwarf_line_size from the partial
+       symbol table.
+
+2002-05-10  Petr Sorfa  <petrs@caldera.com>
+
+       * ia64-tdep.c: Handle breakpoints on L instruction type
+       in MLX instruction bundle by moving the breakpoint to
+       the third slot (X instruction type) as L holds only data.
+
+2002-05-10  Kevin Buettner  <kevinb@redhat.com>
+
+       * dbxread.c (discarding_local_symbols_complaint): New complaint.
+       (process_one_symbol): Complain about discarding local symbols
+       due to a misplaced N_LBRAC entry.
+
+2002-05-09  Elena Zannoni  <ezannoni@redhat.com>
+
+       From Daniel Berlin <dan@cgsoftware.com>
+       * linespec.c (find_toplevel_char): '<' and '>' also increase and
+       decrease the depth we are at, in the case of templates.
+
+2002-05-09  Daniel Jacobowitz  <drow@mvista.com>
+
+       * mips-tdep.c (mips_float_register_type): New function.
+       (mips_double_register_type): New function.
+       (mips_print_register): Use them.
+       (do_fp_register_row): Likewise.
+
+2002-05-09  Daniel Jacobowitz  <drow@mvista.com>
+
+       * signals/signals.c (signals): Remove conditional compilation around
+       Mach-specific signals.  Move them to after TARGET_SIGNAL_DEFAULT.
+       (target_signal_from_name): Loop until TARGET_SIGNAL_LAST.
+
+2002-05-09  Michael Snyder  <msnyder@redhat.com>
+
+       * remote-rdp.c (remote_rdp_can_run): Remove.
+
+2002-05-09  Tom Tromey  <tromey@redhat.com>
+
+       * jv-valprint.c (java_val_print): Handle `char' as a special case
+       of TYPE_CODE_INT.
+
+2002-05-09  Michael Snyder  <msnyder@redhat.com>
+
+       * arm-tdep.c (arm_scan_prologue): Accept strb r(0123),[r11,#-nn],
+       strh r(0123),[r11,#-nn], str r(0123),[r11,#-nn], as well as
+       strb r(0123),[sp,#nn], strh r(0123),[sp,#nn] and
+       str r(0123),[sp,#nn].
+       (arm_skip_prologue): Ditto.  Also make disassembly
+       order-independent by placing it in a loop.
+
+2002-05-06  Michael Snyder  <msnyder@redhat.com>
+
+       * stabsread.c (read_type): Add recognition for new attribute:
+       "@V;" means that an array type is actually a vector.
+       This is analogous to the vector flag that's been added to dwarf2.
+
+2002-05-09  Mark Kettenis  <kettenis@gnu.org>
+
+       * i386-tdep.h (i386_abi): New enum.
+       (struct gdbarch_tdep): Replace os_ident member with abi.
+       (i386_gdbarch_register_os_abi): New prototype.
+       * i386-tdep.c (i386_abi_names): New array.
+       (process_note_abi_tag_sections): Removed.
+       (process_note_sections): New function.
+       (i386_elf_abi_from_note, i386_elf_abi): New functions.
+       (struct i386_abi_handler): New struct.
+       (i386_abi_handler_list): New variable.
+       (i386_gdbarch_register_os_abi): New function.
+       (i386_gdbarch_init): Adapt for the changes given above.
+
+2002-05-08  Daniel Jacobowitz  <drow@mvista.com>
+
+       * gregset.h: Say "GNU/Linux".
+
+2002-05-08  Elena Zannoni  <ezannoni@redhat.com>
+
+       * gdbtypes.c : Add new builtin type for 64 bit vectors.
+        (build_gdbtypes): Build builtin_type_v2_float.
+       (_initialize_gdbtypes): Register new builtin type.
+
+2002-05-08  Andrew Cagney  <ac131313@redhat.com>
+
+       * gdbarch.sh (init_gdbarch_swap): Do not clear the swap section.
+       (clear_gdbarch_swap): New function.
+       (initialize_non_multiarch): Call.
+       (gdbarch_update_p): Before calling init(), swap out and clear the
+       existing architecture.
+       * gdbarch.c: Regenerate.
+
+2002-05-08  Jason Thorpe  <thorpej@wasabisystems.com>
+
+       * config/djgpp/fnchange.lst: Add alphanbsd-nat.c and
+       alphanbsd-tdep.c.
+
+2002-05-08  Jason Thorpe  <thorpej@wasabisystems.com>
+
+       * sh-nbsd-nat.c: Rename to...
+       * shnbsd-nat.c: ...this.
+       * sh-nbsd-tdep.c: Rename to...
+       * shnbsd-tdep.c: ...this.
+       * sh-nbsd-tdep.h: Rename to...
+       * shnbsd-tdep.h: ...this.
+       * config/sh/nbsd.mh: Use shnbsd-nat.o.
+       * config/sh/nbsd.mt: Use shnbsd-tdep.o.
+
+2002-05-08  Richard Earnshaw  <rearnsha@arm.com>
+
+       * remote-rdi.c (_initializie_remote_rdi): Use ANSI-style string
+       concatenation for command help messages.
+
+2002-05-08  Jason Thorpe  <thorpej@wasabisystems.com>
+
+       * NEWS: Note new sh*-*-netbsdelf* configuration.
+       * configure.host: Set gdb_host_cpu to sh for all sh*.
+       (sh*-*-netbsdelf*): New host.
+       * configure.tgt: Set gdb_target_cpu to sh for all sh*.
+       (sh*-*-netbsdelf*): New target.
+       * sh-nbsd-nat.c: New file.
+       * sh-nbsd-tdep.c: New file.
+       * sh-nbsd-tdep.h: New file.
+       * config/sh/nbsd.mh: New file.
+       * config/sh/nbsd.mt: New file.
+       * config/sh/nm-nbsd.h: New file.
+       * config/sh/tm-nbsd.h: New file.
+
+2002-05-08  Jason Thorpe  <thorpej@wasabisystems.com>
+
+       * sh-tdep.c (sh_osabi_names): Declare.
+       (process_note_abi_tag_sections): New function.
+       (get_elfosabi): Ditto.
+       (sh_gdbarch_register_os_abi): Ditto.
+       (sh_dump_tdep): Ditto.
+       _initialize_sh_tdep): Use gdbarch_register to register
+       sh_gdbarch_init and sh_dump_tdep.
+       * config/sh/tm-sh.h (sh_osabi): Declare.
+       (gdbarch_tdep): Add sh_osabi and osabi_name members.
+
+2002-05-07  Andrew Cagney  <ac131313@redhat.com>
+
+       * arm-tdep.c (arm_skip_prologue): Handle generic dummy frames.
+       (thumb_scan_prologue): Ditto.
+       (arm_find_callers_reg): Ditto.
+       (arm_frame_chain): Ditto.
+       (arm_init_extra_frame_info): Ditto.
+       (arm_frame_saved_pc): Ditto.
+       (arm_pop_frame): Ditto.
+       (arm_push_return_address): New function.
+       (arm_gdbarch_init): Initialize use_generic_dummy_frames,
+       call_dummy_location, call_dummy_breakpoint_offset_p,
+       call_dummy_breakpoint_offset, call_dummy_p,
+       call_dummy_stack_adjust_p, call_dummy_words,
+       sizeof_call_dummy_words, call_dummy_start_offset,
+       call_dummy_length, fix_call_dummy, pc_in_call_dummy,
+       call_dummy_address, push_return_address and push_dummy_frame for
+       generic dummy frames.
+
+2002-05-07  Jason Thorpe  <thorpej@wasabisystems.com>
+
+       * sh-tdep.c (sh_nofp_frame_init_saved_regs): Fix error in
+       size computation for alloca.
+       (sh_fp_frame_init_saved_regs): Likewise.
+
+2002-05-07  Richard Earnshaw  <rearnsha@arm.com>
+
+       * arm-tdep.h (ARM_MAX_REGISTER_RAW_SIZE): Define.
+       (ARM_MAX_REGISTER_VIRTUAL_SIZE): Define.
+       * arm-tdep.c (arm_store_return_value): Use them.
+       Use FP_REGISTER_RAW_SIZE when setting the FPA return value.
+       * remote-rdp.c (remote_rdp_fetch_register): Use
+       ARM_MAX_REGISTER_RAW_SIZE.
+       (remote_rdp_store_register): Likewise.
+
+2002-05-07  Michal Ludvig  <mludvig@suse.cz>
+
+       * dwarf2cfi.c: Code cleanup, removed unused variables,
+       added default labels to switch {} statements.
+       * x86-64-tdep.c: Ditto.
+       * x86-64-linux-nat.c: Ditto.
+
+2002-05-07  Jason Thorpe  <thorpej@wasabisystems.com>
+
+       * solib.h: Protect against multiple inclusion.
+
+2002-05-06  Jim Blandy  <jimb@redhat.com>
+
+       Add first preprocessor macro-expansion files.
+       * macroexp.c, macroexp.h, macrotab.c, macrotab.h: New files.
+       * Makefile.in (SFILES): Add macrotab.c, macroexp.c.
+       (splay_tree_h, macroexp_h, macrotab_h): New variable.
+       (HFILES_NO_SRCDIR): Add macrotab.h, macroexp.h.
+       (COMMON_OBS): Add macrotab.o, macroexp.o.
+       (macroexp.o, macrotab.o): New rules.
+
+       Separate the job of reading the line number info statement program
+       header (...expialidocious) out into its own function.
+       * dwarf2read.c (struct line_head, struct filenames, struct
+       directories): Replace with...
+       (struct line_header): New structure, containing the full
+       contents of the statement program header, including the
+       include directory and file name tables.
+       (read_file_scope): If we have line number info, instead of just
+       calling dwarf_decode_lines to do all the work, call
+       dwarf_decode_line_header first to get a `struct line_header'
+       containing the data in the statement program header, and then
+       pass that to dwarf_decode_lines, which will pick up where that
+       left off.  Be sure to clean up the `struct line_header' object.
+       (dwarf_decode_line_header, free_line_header, add_include_dir,
+       add_file_name): New functions.
+       (dwarf_decode_lines): Move all the code to read the statement
+       program header into dwarf_decode_line_header.  Take the line
+       header it built as the first argument, instead of the offset to
+       the compilation unit's line number info.  Use the new `struct
+       line_header' type instead of the old structures.  No need to do
+       cleanups here now, since we don't allocate anything.
+       (dwarf2_statement_list_fits_in_line_number_section,
+       dwarf2_line_header_too_long): New complaints.
+
+2002-05-06  Elena Zannoni  <ezannoni@redhat.com>
+
+       * gdbtypes.c (init_vector_type): New function.
+       (build_builtin_type_vec128): Simplify the representation of SIMD
+       registers.
+       (build_gdbtypes): Initialize new builtin vector types.
+       (_initialize_gdbtypes): Register new vector types with gdbarch.
+       (builtin_type_v4_float, builtin_type_v4_int32,
+       builtin_type_v8_int16, builtin_type_v16_int8,
+       builtin_type_v2_int32, builtin_type_v4_int16,
+       builtin_type_v8_int8): New (renamed) SIMD types.
+
+2002-05-06  Mark Kettenis  <kettenis@gnu.org>
+
+       * i387-nat.c (i387_fill_fsave): Use regcache_collect.
+       (i387_fill_fxsave): Likewise.
+
+2002-05-05  Alexandre Oliva  <aoliva@redhat.com>
+
+       * alpha-tdep.c (alpha_extract_return_value): Don't use
+       non-constant array size in prototype.
+
+2002-05-04  Andrew Cagney  <ac131313@redhat.com>
+
+       From Brian Taylor <briant at model dot com>:
+       * ui-out.c (ui_out_field_core_addr): Use the function
+       longest_local_hex_string_custom'to format addresses > 32 bits
+       wide.
+
+       * ui-out.c (ui_out_field_core_addr): Update comment.
+
+2002-05-04  Andrew Cagney  <ac131313@redhat.com>
+
+       * stack.c (select_and_print_frame): Make static.  Delete the
+       parameter `level'.
+       (func_command): Update call.
+       (select_frame_command): Delete code computing the frame level.
+       * frame.h (select_and_print_frame): Delete declaration.
+
+2002-05-04  Andrew Cagney  <ac131313@redhat.com>
+
+       * sparc-tdep.c (sparc_get_saved_register): Comment why
+       get_prev_frame call is safe.
+
+2002-05-04  Andrew Cagney  <ac131313@redhat.com>
+
+       * frame.h (select_frame): Delete level parameter.
+       * stack.c (select_frame): Update.  Use frame_relative_level to
+       obtain the frame's level.
+       (select_and_print_frame): Update call.
+       (select_frame_command): Ditto.
+       (up_silently_base): Ditto.
+       (down_silently_base): Ditto.
+       * ocd.c (ocd_start_remote): Ditto.
+       * remote-rdp.c (remote_rdp_open): Ditto.
+       * remote-mips.c (mips_initialize): Ditto.
+       (common_open): Ditto.
+       * remote-e7000.c (e7000_start_remote): Ditto.
+       * m3-nat.c (select_thread): Ditto.
+       * hppa-tdep.c (child_get_current_exception_event): Ditto.
+       (child_get_current_exception_event): Ditto.
+       * varobj.c (varobj_create): Ditto.
+       (varobj_update): Ditto.
+       (c_value_of_root): Ditto.
+       * tracepoint.c (finish_tfind_command): Ditto.
+       * corelow.c (core_open): Ditto.
+       * arch-utils.c (generic_prepare_to_proceed): Ditto.
+       * thread.c (info_threads_command): Ditto.
+       (switch_to_thread): Ditto.
+       * infrun.c (normal_stop): Ditto.
+       (restore_selected_frame): Ditto.
+       (restore_inferior_status): Ditto.
+       * breakpoint.c (insert_breakpoints): Ditto.
+       (watchpoint_check): Ditto.
+       (bpstat_stop_status): Ditto.
+       (do_enable_breakpoint): Ditto.
+       * blockframe.c (flush_cached_frames): Ditto.
+       (reinit_frame_cache): Ditto.
+
+2002-05-04  Andrew Cagney  <ac131313@redhat.com>
+
+       * MAINTAINERS (Host/Native): Add Jason Thorpe as NetBSD
+       maintainer.
+
+2002-05-04  Jim Blandy  <jimb@redhat.com>
+
+       * gdbtypes.c (replace_type): Doc fix.
+
+2002-05-04  Andrew Cagney  <ac131313@redhat.com>
+
+       * valprint.c (strcat_longest): Delete commented out function.
+       Update copyright.
+
+2002-05-04  Andrew Cagney  <ac131313@redhat.com>
+
+       * MAINTAINERS: Mark a29k as deleted.
+       * NEWS: Mention that a29k was removed.  Add OBSOLETE section.
+       Move new configurations to the top.
+       * configure.tgt: Remove a29k.
+       * config/a29k/tm-vx29k.h: Delete.
+       * config/a29k/vx29k.mt: Delete.
+       * config/a29k/tm-a29k.h: Delete.
+       * config/a29k/a29k-udi.mt: Delete.
+       * config/a29k/a29k.mt: Delete.
+       * a29k-tdep.c: Delete.
+       * remote-udi.c: Delete.
+       * remote-mm.c: Delete.
+       * remote-eb.c: Delete.
+       * remote-adapt.c: Delete.
+       * Makefile.in: Remove obsolete code.
+       * config/s390/s390x.mt: Ditto.
+       * config/s390/s390.mt: Ditto.
+       * config/sparc/sparclynx.mh: Ditto.
+       * config/sparc/linux.mh: Ditto.
+       * config/pa/hppaosf.mh: Ditto.
+       * config/pa/hppabsd.mh: Ditto.
+       * config/ns32k/nbsd.mt: Ditto.
+       * config/mips/vr5000.mt: Ditto.
+       * config/m68k/sun3os4.mh: Ditto.
+       * config/m68k/nbsd.mt: Ditto.
+       * config/m68k/m68klynx.mh: Ditto.
+       * config/m32r/m32r.mt: Ditto.
+       * config/i386/x86-64linux.mt: Ditto.
+       * config/i386/nbsdelf.mt: Ditto.
+       * config/i386/nbsd.mt: Ditto.
+       * config/i386/i386lynx.mh: Ditto.
+
+2002-05-04  Andrew Cagney  <ac131313@redhat.com>
+
+       * target.c (debug_print_register): New function.  Handle oversize
+       registers.
+       (debug_to_fetch_registers): Call.
+       (debug_to_store_registers): Call.
+
+2002-05-03  Jim Blandy  <jimb@redhat.com>
+
+       * stabsread.c (cleanup_undefined_types): Use replace_type, not memcpy.
+       (read_type): Doc fix.
+       * gdbtypes.c (replace_type): Doc fix.
+
+       * stabsread.c (multiply_defined_struct): New complaint.
+       (read_struct_type): If the type we were passed isn't empty, or
+       incomplete, don't read the new struct type into it; complain,
+       and return the original type unchanged.  Take a new `type_code'
+       argument, which is the type code for the new type.
+       (read_type): Rather than storing the type's type code here, pass
+       it as an argument to read_struct_type, and let that take care of
+       storing it.  That way, we don't overwrite the original type code,
+       so read_struct_type can use it to decide whether we're overwriting
+       something we shouldn't.
+       (complain_about_struct_wipeout): New function.
+
+2002-05-03  Andrew Cagney  <ac131313@redhat.com>
+
+       * gdbarch.sh: Assert that gdbarch is non-NULL.
+       * gdbarch.c: Regenerate.
+
+2002-05-03  Jason Merrill  <jason@redhat.com>
+
+       * gnu-v3-abi.c (gnuv3_rtti_type): If we get confused, just warn
+       and return NULL.
+
+2002-05-03  Michal Ludvig  <mludvig@suse.cz>
+
+       * x86-64-tdep.c (x86_64_dwarf2gdb_regno_map),
+       (x86_64_dwarf2gdb_regno_map_length),
+       (x86_64_dwarf2_reg_to_regnum): Added.
+       (x86_64_gdbarch_init): Added registration of x86_64_dwarf2_reg_to_regnum.
+       (x86_64_gdbarch_init): Renamed from i386_gdbarch_init.
+       (_initialize_x86_64_tdep): Synced with the change above.
+       (x86_64_skip_prologue): Reformulated message.
+
+2002-05-03  Pierre Muller  <muller@ics.u-strasbg.fr>
+
+       * f-exp.y: Also use new prev_lexptr variable
+       to improve error reporting. Based on Michael Snyder
+       2002-04-24 dated patch to c-exp.y.
+       * jv-exp.y: Likewise.
+       * m2-exp.y: Likewise.
+
+2002-05-02  Elena Zannoni  <ezannoni@redhat.com>
+
+       * valops.c (value_arg_coerce): Don't coerce arrays to pointers if
+       we are dealing with vectors.
+
+2002-05-02  Pierre Muller  <muller@ics.u-strasbg.fr>
+
+       * config/m68k/tm-nbsd.h: Obvious fix,
+       correct machine name.
+
+2002-05-02  Pierre Muller  <muller@ics.u-strasbg.fr>
+
+       * p-typeprint.c (pascal_type_print_base): Add support
+       for TYPE_CODE_STRING and TYPE_CODE_BITSTRING.
+
+2002-05-02  Pierre Muller  <muller@ics.u-strasbg.fr>
+
+       * p-lang.c (pascal_create_fundamental_type): Use TYPE_CODE_CHAR
+       for fondamental pascal 'char' type.
+
+2002-05-02  Pierre Muller  <muller@ics.u-strasbg.fr>
+
+       * p-lang.h (is_pascal_string_type): Declaration changed,
+       new sixth argument of type char ** added.
+       * p-lang.c (is_pascal_string_type): Implementation
+       changed. Args length_pos, length_size, string_pos, char_size
+       can now be NULL. New argument arrayname set to the field
+       name of the char array. Return value set to char array
+       field index plus one.
+       * p-valprint.c (pascal_val_print): Adapt to new declaration of
+       is_pascal_string_type function.
+
+2002-05-02  Andrew Cagney  <cagney@redhat.com>
+
+       * gdbarch.sh (gdbarch_update_p): Revert 2002-05-02 Andrew Cagney
+       <cagney@redhat.com> change.
+       * gdbarch.c: Regenerate.
+
+2002-05-02  Andrew Cagney  <cagney@redhat.com>
+
+       * gdbarch.sh (gdbarch_update_p): Swap out the old architecture
+       before probing for a new one.  Detect errorenous gdbarch_init
+       functions.
+       * gdbarch.c: Regenerate.
+
+2002-05-01  Andrew Cagney  <cagney@redhat.com>
+
+       * config/mn10200/tm-mn10200.h: Include "symfile.h" and "symtab.h".
+       * config/mcore/tm-mcore.h: Ditto.  Update copyright.
+       * config/v850/tm-v850.h: Ditto.  Update copyright.
+
+2002-04-30  Andrew Cagney  <ac131313@redhat.com>
+
+       * cris-tdep.c (cris_gdbarch_init): Use arches instead of
+       current_gdbarch.
+
+2002-04-30  Michael Snyder  <msnyder@redhat.com>
+
+       * arm-tdep.c: Whitespace clean-ups.
+       (arm_skip_prologue): Fix thinko; two lines
+       should have been removed as part of 4/24 change.
+
+2002-04-30  Kevin Buettner  <kevinb@redhat.com>
+
+       * rs6000-tdep.c: Added comment describing how fpscr register
+       numbers were chosen.
+
+2002-04-30  Michael Snyder  <msnyder@redhat.com>
+
+       * gnu-nat.c (gnu_find_memory_regions): Fix merge botch.
+
+2002-04-29  Elena Zannoni  <ezannoni@redhat.com>
+
+       * hpread.c (DNTT_TYPE_VECTOR): Rename from TYPE_VECTOR.
+       (DNTT_TYPE_VECTOR_LENGTH): Rename from TYPE_VECTOR_LENGTH.
+       (hpread_symfile_init, hpread_lookup_type): Substitute throughout.
+
+2002-04-29  Kevin Buettner  <kevinb@redhat.com>
+
+       From Louis Hamilton <hamilton@redhat.com>:
+       * rs6000-tdep.c (coff/xcoff.h, libxcoff.h): Include.
+       * xcoffread.c (coff/xcoff.h, libxcoff.h): Likewise.
+       * rs6000-tdep.c (rs6000_gdbarch_init): Use bfd_xcoff_is_xcoff64(),
+       not bfd-private xcoff data, to determine wordsize.
+       * xcoffread.c (read_xcoff_xymtab, read_symbol_lineno): Likewise.
+
+2002-04-29  Andrew Cagney  <ac131313@redhat.com>
+
+       GDB 5.2 released from 5.2 branch.
+
+2002-04-29  Michal Ludvig  <mludvig@suse.cz>
+
+       * x86-64-linux-nat.c (fill_gregset): Explicit cast to avoid warning.
+       * x86-64-tdep.c (i386_gdbarch_init): Ditto.
+       (x86_64_register_info_table): Added comments with register numbers.
+
+2002-04-29  Elena Zannoni  <ezannoni@redhat.com>
+
+       * rs6000-tdep.c (rs6000_extract_return_value,
+       rs6000_store_return_value): Handle returning vectors.
+       (rs6000_gdbarch_init): Use
+       ppc_sysv_abi_broken_use_struct_convention for native sysv cases.
+       * ppc-linux-tdep.c (ppc_sysv_abi_broken_use_struct_convention):
+       New function.
+       (ppc_sysv_abi_use_struct_convention): Deal with functions returning
+       vectors.
+       (ppc_sysv_abi_push_arguments): Handle vector parameters.
+       * ppc-tdep.h (ppc_sysv_abi_broken_use_struct_convention): Export.
+
+2002-04-24  Pierre Muller  <ics.u-strasbg.fr>
+
+       * hpread.c (hpread_psymtab_to_symtab_1,
+       hpread_psymtab_to_symtab): Replace fprintf tab_to_s...)
+       with fprintf_unfiltered (gdb_stderr,...).
+
+2002-04-24  Pierre Muller  <ics.u-strasbg.fr>
+
+       * remote-array.c (printf_monitor, write_monitor,
+       array_insert_breakpoint, array_remove_breakpoint ):
+       Replace fprintf (stderr,...
+       with fprintf_unfiltered (gdb_stderr,....
+       * remote-es.c: Likewise.
+       * remote-os9k.c: Likewise.
+       * remote-st.c: Likewise.
+
+2002-04-28  Andreas Schwab  <schwab@suse.de>
+
+       * config/s390/s390.mh (NATDEPFILES): Remove solib.o, add
+       linux-proc.o and gcore.o.
+
+2002-04-26  Michal Ludvig  <mludvig@suse.cz>
+
+       * x86-64-tdep.c (x86_64_skip_prologue): Print note when debugging
+       code without frame pointers.
+
+2002-04-26  Andrew Cagney  <ac131313@redhat.com>
+
+       * sparc-tdep.c (sparc_gdbarch_init): Add comment explaining why
+       ON_STACK is needed.
+
+2002-04-26  Ben Elliston  <bje@redhat.com>
+
+       * target.c (do_xfer_memory): Correct reference to the new option
+       "trust-readonly-sections".
+
+2002-04-26  Elena Zannoni  <ezannoni@redhat.com>
+
+       * gdbtypes.h (TYPE_FLAG_VECTOR, TYPE_VECTOR): Define.
+       * gdbtypes.c (recursive_dump_type): Output the vector flag.
+       * dwarf2read.c (dwarf_attr_name): Handle new attribute for
+       vectors.
+       (read_array_type): Record the fact that this array type is really a
+       vector (i.e. are passed in by value).
+
+2002-04-26  Jason Thorpe  <thorpej@wasabisystems.com>
+
+       * alpha-tdep.h (gdbarch_tdep): Add sigcontext_addr member.
+       * alpha-tdep.c (alpha_sigcontext_addr): New function.
+       (alpha_find_saved_regs): Use alpha_sigcontext_addr.
+       (alpha_gdbarch_init): Initialize tdep->sigcontext_addr.
+       * alpha-linux-tdep.c: Include frame.h.
+       (alpha_linux_sigcontext_addr): New function.
+       (alpha_linux_init_abi): Set tdep->sigcontext_addr to
+       alpha_linux_sigcontext_addr.
+       * alpha-osf1-tdep.c: Include gdbcore.h.
+       (alpha_osf1_sigcontext_addr): New function.
+       (alpha_osf1_init_abi): Set tdep->sigcontext_addr to
+       alpha_osf1_sigcontext_addr.
+       * config/alpha/tm-alpha.h (SIGCONTEXT_ADDR): Remove.
+       * config/alpha/tm-alphalinux.h (SIGCONTEXT_ADDR): Remove.
+
+2002-04-26  Andrew Cagney  <ac131313@redhat.com>
+
+       * stack.c (selected_frame_level):
+       (select_frame): Do not set selected_frame_level.
+       * frame.h (selected_frame_level): Delete declaration.
+
+2002-04-26  Andrew Cagney  <ac131313@redhat.com>
+
+       * rs6000-tdep.c (rs6000_gdbarch_init): Only set
+       convert_from_func_ptr-addr when AIX / PowerOpen.
+
+2002-04-25  Andrew Cagney  <ac131313@redhat.com>
+
+       * valops.c (hand_function_call): Call
+       generic_save_call_dummy_addr.
+       * frame.h (generic_save_call_dummy_addr): Declare.
+       * blockframe.c (struct dummy_frame): Add fields call_lo and
+       call_hi.
+       (generic_find_dummy_frame): Check for PC in range call_lo to
+       call_hi instead of entry_point_address.
+       (generic_pc_in_call_dummy): Search the dummy frames for a PC in
+       the call_lo to call_hi range.  Allow for DECR_PC_AFTER_BREAK.
+       (generic_save_call_dummy_addr): New function.
+
+2002-04-24  David S. Miller  <davem@redhat.com>
+
+       * sparc-tdep.c (sparc_gdbarch_skip_prologue): Kill, duplicates
+       sparc_skip_prologue.
+       (sparc_skip_prologue): Kill frameless_p arg, and use line number
+       information to find prologue when possible.
+       (sparc_prologue_frameless_p): Call examine_prologue directly.
+       (sparc_gdbarch_init): Update set_gdbarch_skip_prologue call.
+       * config/sparc/tm-sparc.h (sparc_skip_prologue): Update for killed
+       second argument.
+       (SKIP_PROLOGUE): Likewise.
+
+2002-04-25  Jason Thorpe  <thorpej@wasabisystems.com>
+
+       * alpha-tdep.c (alpha_skip_prologue_internal): Remove
+       GDB_TARGET_HAS_SHARED_LIBS #ifdef and update comment to
+       indicate that the condition it was testing is always true.
+       * config/alpha/nm-linux.h (GDB_TARGET_HAS_SHARED_LIBS): Remove.
+       * config/alpha/nm-nbsd.h (GDB_TARGET_HAS_SHARED_LIBS): Ditto.
+       * config/alpha/nm-osf.h (GDB_TARGET_HAS_SHARED_LIBS): Ditto.
+
+2002-04-25  Jason Thorpe  <thorpej@wasabisystems.com>
+
+       * alpha-tdep.h (gdbarch_tdep): Add jb_pc and jb_elt_size members.
+       * alpha-linux-tdep.c (alpha_linux_init_abi): Initialize
+       tdep->jb_pc and tdep->jb_elt_size.
+       * alpha-osf1-tdep.c (alpha_osf1_init_abi): Likewise.
+       * alphafbsd-tdep.c (alphafbsd_init_abi): Likewise.
+       * alphanbsd-tdep.c (alphanbsd_init_abi): Likewise.
+       * alpha-nat.c (get_longjmp_target): Remove.
+       (JB_ELEMENT_SIZE): Ditto.
+       (JB_PC): Ditto.
+       * alpha-tdep.c (alpha_get_longjmp_target): New function.
+       (alpha_gdbarch_init): Default tdep->jb_pc to -1.  If the
+       OS ABI sets jb_pc to a valid value, set gdbarch_get_longjmp_target
+       to alpha_get_longjmp_target.
+       (alpha_dump_tdep): Report tdep->jb_pc and tdep->jb_elt_size.
+       * config/alpha/nm-linux.h (GET_LONGJMP_TARGET): Remove.
+       * config/alpha/nm-osf.h (GET_LONGJMP_TARGET): Remove.
+
+2002-04-25  Andrew Cagney  <ac131313@redhat.com>
+
+       * README: Update to GDB 5.2.
+
+2002-04-25  Andrew Cagney  <ac131313@redhat.com>
+
+       * gdbarch.sh (LC_ALL): Set to `c'.
+
+2002-04-25  Theodore A. Roth  <troth@verinet.com>
+
+       * avr-tdep.c: Ran through gdb_indent.sh.
+
+2002-04-25  Theodore A. Roth  <troth@verinet.com>
+
+       * MAINTAINERS: Add myself as AVR maintainer.
+       * NEWS: Note new target avr.
+
+2002-04-25  Theodore A. Roth  <troth@verinet.com>
+
+       * Makefile.in: Add support for AVR target.
+       * configure.tgt: Add support for AVR target.
+       * avr-tdep.c: New file
+       * config/avr/avr.mt: New file.
+
+2002-04-25  Theodore A. Roth  <troth@verinet.com>
+
+       * MAINTAINERS: Add myself to write-after-approval.
+
+2002-04-24  Pierre Muller  <ics.u-strasbg.fr>
+
+       * f-lang.c (get_bf_for_fcn): Replace fprintf (stderr,...
+       with fprintf_unfiltered (gdb_stderr,....
+
+2002-04-25  Pierre Muller  <muller@ics.u-strasbg.fr>
+
+       Fix PR gdb/508.
+       * symfile.c (add_filename_language): Fix wrong xrealloc size argument.
+
+2002-04-25  Pierre Muller  <muller@ics.u-strasbg.fr>
+
+       * p-exp.y: Also use new prev_lexptr variable
+       to improve error reporting. Based on Michael Snyder
+       2002-04-24 dated patch to c-exp.y.
+
+2002-04-25  Jason Thorpe  <thorpej@wasabisystems.com>
+
+       * alpha-tdep.c (alpha_breakpoint_from_pc): New function.
+       (alpha_gdbarch_init): Set gdbarch_breakpoint_from_pc to
+       alpha_breakpoint_from_pc.  Set gdbarch_function_start_offset
+       to 0.
+       * config/alpha/tm-alpha.h: Remove forward decls of struct type
+       and struct value.
+       (FUNCTION_START_OFFSET): Remove.
+       (BREAKPOINT): Ditto.
+
+2002-04-25  Jason Thorpe  <thorpej@wasabisystems.com>
+
+       * MAINTAINERS: Reflect that multi-arch is enabled for VAX.
+       * NEWS: Ditto.
+
+2002-04-24  Jason Thorpe  <thorpej@wasabisystems.com>
+
+       * alpha-linux-tdep.c (alpha_linux_pc_in_sigtramp): New function.
+       (alpha_linux_init_abi): Set gdbarch_pc_in_sigtramp to
+       alpha_linux_pc_in_sigtramp.
+       * alpha-osf1-tdep.c (alpha_osf1_pc_in_sigtramp): New function.
+       (alpha_osf1_init_abi): Set gdbarch_pc_in_sigtramp to
+       alpha_osf1_pc_in_sigtramp.
+       * alpha-tdep.c (alpha_osf_in_sigtramp): Remove.
+       * alphafbsd-tdep.c (alphafbsd_pc_in_sigtramp): New function.
+       (alphafbsd_init_abi): Set gdbarch_pc_in_sigtramp to
+       alphafbsd_pc_in_sigtramp.
+       * alphanbsd-tdep.c (alphanbsd_pc_in_sigtramp): New function.
+       (alphanbsd_init_abi): Set gdbarch_pc_in_sigtramp to
+       alphanbsd_pc_in_sigtramp.
+       * config/alpha/tm-alpha.h (IN_SIGTRAMP): Remove.
+       * config/alpha/tm-alphalinux.h (IN_SIGTRAMP): Remove.
+
+2002-04-24  Jason Thorpe  <thorpej@wasabisystems.com>
+
+       * config/alpha/nbsd.mh (NATDEPFILES): Remove solib-legacy.o.
+
+2002-04-24  Jason Thorpe  <thorpej@wasabisystems.com>
+
+       * Makefile.in (ALLDEPFILES): Add alphanbsd-nat.c and
+       alphanbsd-tdep.c.
+       (alphanbsd-nat.o): New dependency list.
+       (alphanbsd-tdep.o): Ditto.
+       * NEWS: Note new native NetBSD/alpha configuration.
+       * alphanbsd-nat.c: New file.
+       * alphanbsd-tdep.c: Ditto.
+       * configure.host (alpha*-*-netbsd*): New host.
+       * configure.tgt (alpha*-*-netbsd*): New target.
+       * config/alpha/nbsd.mh: New file.
+       * config/alpha/nbsd.mt: Ditto.
+       * config/alpha/nm-nbsd.h: Ditto.
+       * config/alpha/tm-nbsd.h: Ditto.
+
+2002-04-24  Jason Thorpe  <thorpej@wasabisystems.com>
+
+       * Makefile.in (ALLDEPFILES): Add alpha-osf1-tdep.c.
+       (alpha-osf1-tdep.o): New dependency list.
+       * alpha-tdep.h (gdbarch_tdep): Add dynamic_sigtramp_offset
+       and skip_sigtramp_frame members.
+       * alpha-linux-tdep.c: Include gdbcore.h.
+       (alpha_linux_sigtramp_offset): Change return type to LONGEST.
+       (alpha_linux_init_abi): Initialize tdep->dynamic_sigtramp_offset.
+       * alpha-osf1-tdep.c: New file.
+       * alpha-tdep.c (alpha_osf_skip_sigtramp_frame): Moved to
+       alpha-osf1-dep.c.
+       (alpha_frame_past_sigtramp_frame): New function.
+       (alpha_dynamic_sigtramp_offset): Ditto.
+       (alpha_proc_desc_is_dyn_sigtramp): Ditto.
+       (alpha_set_proc_desc_is_dyn_sigtramp): Ditto.
+       (ALPHA_PROC_SIGTRAMP_MAGIC): Define.
+       (push_sigtramp_desc): Use alpha_set_proc_desc_is_dyn_sigtramp.
+       (after_prologue): Use alpha_proc_desc_is_dyn_sigtramp.
+       (find_proc_desc): Use alpha_dynamic_sigtramp_offset.
+       (alpha_frame_chain): Use alpha_frame_past_sigtramp_frame.
+       (alpha_init_extra_frame_info): Use alpha_proc_desc_is_dyn_sigtramp.
+       (alpha_pop_frame): Use alpha_proc_desc_is_dyn_sigtramp.
+       (alpha_gdbarch_init): Initialize tdep->dynamic_sigtramp_offset
+       and tdep->skip_sigtramp_frame.  Set gdbarch_skip_trampoline_code
+       to find_solib_trampoline_target.
+       * config/alpha/alpha-osf1.mt (TDEPFILES): Add alpha-osf1-tdep.o.
+       * config/alpha/tm-alpha.h: Remove inclusion of regcache.h.
+       (SKIP_TRAMPOLINE_CODE): Remove.
+       (PROC_DESC_IS_DYN_SIGTRAMP): Ditto.
+       (SET_PROC_DESC_IS_DYN_SIGTRAMP): Ditto.
+       (DYNAMIC_SIGTRAMP_OFFSET): Ditto.
+       (FRAME_PAST_SIGTRAMP_FRAME): Ditto.
+       * config/alpha/tm-alphalinux.h (PROC_DESC_IS_DYN_SIGTRAMP): Remove.
+       (PROC_SIGTRAMP_MAGIC): Ditto.
+       (PROC_DESC_IS_DYN_SIGTRAMP): Ditto.
+       (SET_PROC_DESC_IS_DYN_SIGTRAMP): Ditto.
+       (SET_PROC_DESC_IS_DYN_SIGTRAMP): Ditto.
+       (DYNAMIC_SIGTRAMP_OFFSET): Ditto.
+       (FRAME_PAST_SIGTRAMP_FRAME): Ditto.
+
+2002-04-24  Jason Thorpe  <thorpej@wasabisystems.com>
+
+       * NEWS: Note that Alpha targets are now multi-arch.
+
+2002-04-24  Michael Snyder  <msnyder@redhat.com>
+
+       * parser-defs.h (prev_lexptr): New external variable.
+       * parse.c (parse_exp_1): Set prev_lexptr to null before
+       calling the language-specific parser.
+       * c-exp.y (yylex): Set prev_lexptr to start of current token.
+       (yyerror): Use prev_lexptr in error reporting.
+
+2002-04-24  Daniel Jacobowitz  <drow@mvista.com>
+
+       * config/i386/tm-linux.h: Define FILL_FPXREGSET.
+       * gregset.h: If FILL_FPXREGSET is defined, provide
+       gdb_fpxregset_t, supply_fpxregset, and fill_fpxregset.
+       * linux-proc.c (linux_do_thread_registers): If FILL_FPXREGSET
+       is defined, call fill_fpxregset.
+
+2002-04-24  Roland McGrath  <roland@frob.com>
+
+       * config/i386/i386gnu.mh (NATDEPFILES): Add core-regset.o here.
+       * i386gnu-nat.c [HAVE_SYS_PROCFS_H]
+       (supply_gregset, supply_fpregset): New functions.
+
+       * gnu-nat.c (gnu_find_memory_regions): New function.
+       (init_gnu_ops): Set `to_find_memory_regions' hook to that.
+       (gnu_xfer_memory): Add a cast.
+
+2002-04-24  Michael Snyder  <msnyder@redhat.com>
+
+       * arm-tdep.c (arm_scan_prologue): Move "mov ip, sp" into the
+       loop.  Add handling for "str lr, [sp, #-4]!" and for saves
+       of argument regs ("str r(0123), [r11, #-nn"]).
+       (arm_skip_prologue): Better handling for frameless functions.
+       Treat "mov ip, sp" as optional.  Recognize "str lr, [sp, #-4]".
+       (arm_skip_prologue): Recognize str r(0123), [r11, #-nn].
+
+Wed Apr 24 14:22:21 2002  Andrew Cagney  <cagney@redhat.com>
+
+       * arm-tdep.c (arm_gdbarch_init): Add comment that NUM_REGS nor
+       NUM_PSEUDO_REGS can be used.
+
+2002-04-24  Andrew Cagney  <ac131313@redhat.com>
+
+       * arch-utils.h: Update copyright.
+
+       * gdbarch.sh (PC_IN_SIGTRAMP): Add.
+       * gdbarch.h, gdbarch.c: Re-generate.
+
+       * inferior.h (IN_SIGTRAMP): Delete definition.
+       * arch-utils.c (legacy_pc_in_sigtramp): New function.
+       * arch-utils.h (legacy_pc_in_sigtramp): Declare.
+
+       * mips-tdep.c (mips_init_extra_frame_info): Use PC_IN_SIGTRAMP.
+       (mips_dump_tdep): Do not print value of IN_SIGTRAMP.
+       * hppa-tdep.c (pc_in_interrupt_handler):  Use PC_IN_SIGTRAMP.
+       (find_proc_framesize): Ditto.
+       * alpha-tdep.c (alpha_osf_skip_sigtramp_frame): Ditto.
+       (alpha_init_extra_frame_info): Ditto.
+       * infrun.c (handle_inferior_event): Ditto.
+       (handle_inferior_event): Ditto.
+       (check_sigtramp2): Ditto.
+       * blockframe.c (create_new_frame): Ditto.
+       (get_prev_frame): Ditto.
+       * ppc-linux-tdep.c: Update comments.
+       * i386-linux-tdep.c: Update comments.
+       * breakpoint.c (bpstat_what): Update comment.
+
+2002-04-24  David S. Miller  <davem@redhat.com>
+
+       * i960-tdep.c (register_in_window_p): New function.
+       (i960_find_saved_register): Use it instead of
+       REGISTER_IN_WINDOW_P.
+       * config/i960/tm-i960.h (REGISTER_IN_WINDOW): Delete.
+
+       * symtab.h (find_stab_function_addr): Kill extern.
+       * minsyms.c (find_stab_function_addr): Remove from here...
+       * dbxread.c: ... to here, and mark it static.
+
+2002-04-20  David S. Miller  <davem@redhat.com>
+
+       * sparc-tdep.c (sparc_pop_frame): Only need to allocate
+       SPARC_INTREG_SIZE * 16 bytes for reg_temp.
+
+2002-04-21  David S. Miller  <davem@redhat.com>
+
+       * remote-vxsparc.c (vx_read_register): Fix typo, we want
+       REGISTER_RAW_SIZE of SP_REGNUM not CORE_ADDR.
+       (vx_write_register): Likewise.
+
+2002-04-23  J. Brobecker  <brobecker@gnat.com>
+
+       * source.c (is_regular_file): New function.
+       (openp): Check wether file to open is a regular file
+       to avoid opening directories.
+
+2002-04-22  Jason Thorpe  <thorpej@wasabisystems.com>
+
+       * findvar.c (extract_signed_integer): Cast printf argument
+       to suppress format warning.
+       (extract_unsigned_integer): Likewise.
+       * infcmd.c (registers_info): Likewise.
+       * top.c (get_prompt_1): Likewise.
+       * valops.c (value_assign): Likewise.
+       * valprint.c (print_decimal): Likewise.
+
+2002-04-22  H.J. Lu  (hjl@gnu.org)
+
+       * c-exp.y (typebase): Support
+
+       [long|long long|short] [signed|unsigned] [int|]
+
+       and
+
+       signed [long|long long|short] int
+
+2002-04-22  Jason Thorpe  <thorpej@wasabisystems.com>
+
+       * Makefile.in (vax-tdep.o): Add $(arch_utils_h), $(inferior_h),
+       and vax-tdep.h.
+       * vax-tdep.h: New file.
+       * vax-tdep.c: Include inferior.h, arch-utils.h, and vax-tdep.h.
+       Make several routines static.
+       (vax_get_saved_register): New function.
+       (vax_gdbarch_init): New function.
+       (_initialize_vax_tdep): Register vax_gdbarch_init.
+       * config/vax/tm-vax.h: Set GDB_MULTI_ARCH to GDB_MULTI_ARCH_PARTIAL.
+       Remove macros now under the control of gdbarch.
+
+2002-04-22  Michael Snyder  <msnyder@redhat.com>
+
+       * arm-tdep.c (arm_skip_prologue): Recognize "sub sp, sp, #nn".
+       Some whitespace and coding standards tweaks.
+
+2002-04-22  Jason Thorpe  <thorpej@wasabisystems.com>
+
+       * vax-tdep.c: Include regcache.h.
+       (vax_call_dummy_words): New.
+       (sizeof_vax_call_dummy_words): New.
+       (vax_fix_call_dummy): New function.
+       (vax_saved_pc_after_call): Ditto.
+       * config/vax/tm-vax.h: Don't include regcache.h.
+       (SAVED_PC_AFTER_CALL): Use vax_saved_pc_after_call.
+       (CALL_DUMMY): Remove.
+       (CALL_DUMMY_WORDS): Define.
+       (SIZEOF_CALL_DUMMY_WORDS): Define.
+       (FIX_CALL_DUMMY): Use vax_fix_call_dummy.
+
+2002-04-18  Michael Snyder  <msnyder@redhat.com>
+
+       * arm-tdep.h: Change regnum defines to enums for ease of debugging.
+
+2002-04-22  Jason Thorpe  <thorpej@wasabisystems.com>
+
+       * vax-tdep.c (vax_frame_chain): New function.
+       (vax_push_dummy_frame): Ditto.
+       (vax_pop_frame): Ditto.
+       * config/vax/tm-vax.h (FRAME_CHAIN): vax_frame_chain.
+       (FRAMELESS_FUNCTION_INVOCATION): Use
+       generic_frameless_function_invocation_not.
+       (PUSH_DUMMY_FRAME): Use vax_push_dummy_frame.
+       (POP_FRAME): Use vax_pop_frame.
+
+2002-04-22  Jason Thorpe  <thorpej@wasabisystems.com>
+
+       * vax-tdep.c (vax_store_struct_return): New function.
+       (vax_extract_return_value): Ditto.
+       (vax_store_return_value): Ditto.
+       (vax_extract_struct_value_address): Ditto.
+       * config/vax/tm-vax.h (STORE_STRUCT_RETURN): Use
+       vax_store_struct_return.
+       (EXTRACT_RETURN_VALUE): Use vax_extract_return_value.
+       (STORE_RETURN_VALUE): Use vax_store_return_value.
+       (EXTRACT_STRUCT_VALUE_ADDRESS): Use vax_extract_struct_value_address.
+
+2002-04-22  Jason Thorpe  <thorpej@wasabisystems.com>
+
+       * vax-tdep.c (vax_frame_saved_pc): New function.
+       (vax_frame_args_address_correct): Ditto.
+       (vax_frame_args_address): Ditto.
+       (vax_frame_locals_address): Ditto.
+       (vax_frame_num_args): Move code to be in proximity to
+       other frame-related functions.
+       * config/vax/tm-vax.h (INNER_THAN): Use core_addr_lessthan.
+       (FRAME_SAVED_PC): Use vax_frame_saved_pc.
+       (FRAME_ARGS_ADDRESS_CORRECT): Use vax_frame_args_address_correct.
+       (FRAME_ARGS_ADDRESS): Use vax_frame_args_address.
+       (FRAME_LOCALS_ADDRESS): Use vax_frame_locals_address.
+
+2002-04-22  H.J. Lu  (hjl@gnu.org)
+
+       * Makefile.in (FLAGS_TO_PASS): Add libdir, mandir, datadir and
+       includedir.
+
+2002-04-22  Jason Thorpe  <thorpej@wasabisystems.com>
+
+       * vax-tdep.c (vax_frame_init_saved_regs): New function.
+       * config/vax/tm-vax.h (FRAME_FIND_SAVED_REGS): Remove.
+       (FRAME_INIT_SAVED_REGS): New macro.
+
+2002-04-22  Jason Thorpe  <thorpej@wasabisystems.com>
+
+       * MAINTAINERS: Reflect that the Alpha target has been multi-arch'd.
+
+2002-04-22  Jason Thorpe  <thorpej@wasabisystems.com>
+
+       * alpha-nat.c (get_longjmp_target): Use ALPHA_* constants
+       where needed.
+       (fetch_osf_core_registers): Likewise.
+       (supply_gregset): Likewise.
+
+2002-04-22  J. Brobecker  <brobecker@gnat.com>
+
+       * symfile.h (get_section_index): Define.
+       * symfile.c (get_section_index): New function.
+       * mdebugread.c (SC_IS_SBSS): New macro.
+       (SC_IS_BSS): Return true for the scBss storage class only, as
+       the scSBss storage class refers to the .sbss section.
+       (parse_partial_symbols): Discard the symbols which associated
+       section does not exist.
+       Make sure to use the .sbss section index for symbols which
+       storage class is scBss, rather than using the .bss section index.
+
+2002-04-22  Jason Thorpe  <thorpej@wasabisystems.com>
+
+       * vax-tdep.c: Update copyright years.
+       (vax_register_name): New function.
+       (vax_register_byte): Ditto.
+       (vax_register_raw_size): Ditto.
+       (vax_register_virtual_size): Ditto.
+       (vax_register_virtual_type): Ditto.
+       * config/vax/tm-vax.h: Update copyright years.
+       (REGISTER_NAMES): Remove.
+       (REGISTER_NAME): Define.
+       (REGISTER_BYTE): Use vax_register_byte.
+       (REGISTER_RAW_SIZE): Use vax_register_raw_size.
+       (REGISTER_VIRTUAL_SIZE): Use vax_register_virtual_size.
+       (REGISTER_VIRTUAL_TYPE): Use vax_register_virtual_type.
+
+2002-04-21  Andrew Cagney  <ac131313@redhat.com>
+
+       * config/sparc/tm-sparc.h (sparc_skip_prologue): Restore
+       declaration
+       * arc-tdep.c (arc_prologue_frameless_p): Fix syntax error.
+
+2002-04-21  David S. Miller  <davem@redhat.com>
+
+       * arch-utils.c (generic_prologue_frameless_p): Kill
+       SKIP_PROLOGUE_FRAMELESS_P code.
+       * config/arc/tm-arc.h (SKIP_PROLOGUE_FRAMELESS_P): Delete
+       references.
+       (PROLOGUE_FRAMELESS_P, arc_prologue_frameless_p): New.
+       * arc-tdep.c (arc_prologue_frameless_p): Implement.
+       * config/arc/tm-sparc.h (SKIP_PROLOGUE_FRAMELESS_P): Delete
+       references.
+       (PROLOGUE_FRAMELESS_P, sparc_prologue_frameless_p): New.
+       * sparc-tdep.c (sparc_prologue_frameless_p): Implement.
+       (sparc_gdbarch_init): Pass it to
+       set_gdbarch_prologue_frameless_p.
+
+2002-04-21  Jason Thorpe  <thorpej@wasabisystems.com>
+
+       * Makefile.in (ALLDEPFILES): Add alphabsd-nat.c.
+       (alphabsd-nat.o): New dependency list.
+
+2002-04-21  Jason Thorpe  <thorpej@wasabisystems.com>
+
+       * Makefile.in (ALLDEPFILES): Add alpha-linux-tdep.c and
+       alphafbsd-tdep.c.
+       (alpha-linux-tdep.o): New dependency list.
+       (alphafbsd-tdep.o): Likewise.
+
+2002-04-21  Jason Thorpe  <thorpej@wasabisystems.com>
+
+       * alpha-linux-tdep.c: New file.  Move alpha_linux_sigtramp_offset
+       to here...
+       * alpha-tdep.c: ...from here.
+       * config/alpha/alpha-linux.mt (TDEPFILES): Add alpha-linux-tdep.o.
+
+2002-04-21  Jason Thorpe  <thorpej@wasabisystems.com>
+
+       * config/alpha/tm-alpha.h: Move alpha_software_single_step
+       prototype from here...
+       * alpha-tdep.h: ...to here.
+
+2002-04-21  Andrew Cagney  <ac131313@redhat.com>
+
+       * frame.h (selected_frame_level): Document as deprecated.
+       (frame_relative_level): Declare.
+       * stack.c (frame_relative_level): New function.
+       (selected_frame_level): Document as deprecated.
+       (select_frame): Do not set the selected_frame_level.
+
+       * stack.c (frame_info, record_selected_frame): Update.
+       (frame_command, current_frame_command): Update.
+       (up_silently_base, up_command, down_silently_base): Update.
+       (down_command): Update.
+       * inflow.c (kill_command): Update.
+       * tracepoint.c (finish_tfind_command): Update.
+       * corelow.c (core_open): Update.
+       * thread.c (info_threads_command): Update.
+       (do_captured_thread_select): Update.
+       * infcmd.c (finish_command): Update.
+       * breakpoint.c (insert_breakpoints, do_enable_breakpoint): Update.
+
+2002-04-21  Jason Thorpe  <thorpej@wasabisystems.com>
+
+       * config/alpha/tm-fbsd.h (FRAME_CHAIN_VALID): Remove.
+
+2002-04-21  Andrew Cagney  <ac131313@redhat.com>
+
+       * arm-tdep.c (arm_breakpoint_from_pc): Make static.  Make return
+       type const.
+
+2002-04-21  Jason Thorpe  <thorpej@wasabisystems.com>
+
+       * alphafbsd-tdep.c: Update copyright years.  Include
+       alpha-tdep.h.
+       (alphafbsd_use_struct_convention): Make static.
+       (alphafbsd_init_abi): New function.
+       (_initialize_alphafbsd_tdep): New function.
+       * config/alpha/tm-fbsd.h: Update copyright years.
+       (USE_STRUCT_CONVENTION): Remove.
+
+2002-04-21  Jason Thorpe  <thorpej@wasabisystems.com>
+
+       * alpha-tdep.c (alpha_abi_handler): New structure to describe
+       an Alpha ABI variant.
+       (alpha_abi_handler_list): Declare.
+       (alpha_gdbarch_register_os_abi): New function.
+       (alpha_gdbarch_init): Give registered ABI variant handlers a
+       chance to tweak the gdbarch once we have set up defaults.
+       * alpha-tdep.h: Prototype alpha_gdbarch_register_os_abi.
+
+2002-04-21  Jason Thorpe  <thorpej@wasabisystems.com>
+
+       * alpha-tdep.c (alpha_gdbarch_init): Set coerce_float_to_double
+       to standard_coerce_float_to_double.
+       * config/alpha/tm-alpha.h (COERCE_FLOAT_TO_DOUBLE): Remove.
+
+2002-04-21  Jason Thorpe  <thorpej@wasabisystems.com>
+
+       * alpha-tdep.h (gdbarch_tdep): Add vm_min_address member.
+       * alpha-tdep.c (heuristic_proc_start): Use vm_min_address
+       from gdbarch_tdep rather than a constant.
+       (alpha_gdbarch_init): Initialize tdep->vm_min_address to
+       the default text address for all Alpha Unix ABIs.
+       (alpha_dump_tdep): Report the value of tdep->vm_min_address.
+       * config/alpha/tm-alpha.h (VM_MIN_ADDRESS): Delete.
+
+2002-04-21  Jason Thorpe  <thorpej@wasabisystems.com>
+
+       * alpha-tdep.h: New file.  Includes several Alpha target constants
+       taken from...
+       * config/alpha/tm-alpha.h: ...here.  Remove macros that we now
+       let gdbarch deal with.
+       (GDB_MULTI_ARCH): Define as GDB_MULTI_ARCH_PARTIAL.
+       * Makefile.in (alpha-nat.o): Add alpha-tdep.h and $(BFD_SRC)/elf-bfd
+       to dependency list.
+       * alpha-nat.c: Include alpha-tdep.h.  Update for adjusted
+       Alpha target register names.
+       * alphabsd-nat.c: Likewise.
+       * alpha-tdep.c: Include alpha-tdep.h.  Update for adjusted
+       Alpha target register names.  Make serveral routines static.
+       (alpha_get_saved_register): New function.
+       (alpha_abi_names): New.
+       (process_note_abi_tag_sections): New function.
+       (get_elfosabi): New function.
+       (alpha_gdbarch_init): New function.
+       (alpha_dump_tdep): New function.
+       (_initialize_alpha_tdep): Register alpha_gdbarch_init.
+
+2002-04-21  Andrew Cagney  <ac131313@redhat.com>
+
+       * frame.c (find_saved_register): Delete #ifdef
+       HAVE_REGISTER_WINDOWS code.
+       * config/sparc/tm-sparc.h: Update comments.
+       * config/i960/tm-i960.h (HAVE_REGISTER_WINDOWS): Delete macro.
+
+2002-04-21  Andrew Cagney  <ac131313@redhat.com>
+
+       * i960-tdep.c (i960_find_saved_register): New function.
+       (i960_get_saved_register): New function.
+       * config/i960/tm-i960.h (GET_SAVED_REGISTER): Define.
+       (i960_get_saved_register): Declare.
+       * config/i960/tm-i960.h, i960-tdep.c: Update copyright.
+
+2002-04-20  David S. Miller  <davem@redhat.com>
+
+       * sparc-nat.c (store-inferior_registers): Fix ambiguous else.
+
+2002-04-20  Andrew Cagney  <ac131313@redhat.com>
+
+       * arm-tdep.c (arm_gdbarch_init): Use gdbarch_num_pseudo_regs
+       instead of NUM_PSEUDO_REGS.
+
+2002-04-20  David S. Miller  <davem@redhat.com>
+
+       * config/sparc/tm-linux.h (GDB_MULTI_ARCH): Define to
+       GDB_MULTI_ARCH_PARTIAL
+       * config/sparc/tm-sp64linux.h (GDB_MULTI_ARCH): Do not
+       define, let tm-sp64.h do it.
+
+2002-04-20  Jason Thorpe  <thorpej@wasabisystems.com>
+
+       * frame.c (find_saved_register): Avoid a NULL pointer
+       dereference and actually walk the frame list.
+
+2002-04-20  Andrew Cagney  <ac131313@redhat.com>
+
+       * gdbarch.sh (gdbarch_update_p): Keep the list of architectures
+       sorted in most most-recent-used order.  Document.
+       * gdbarch.h, gdbarch.c: Regenerate.
+
+2002-04-19  Andrew Cagney  <ac131313@redhat.com>
+
+       * sparc-tdep.c (sparc_get_saved_register): Use get_prev_frame
+       instead of ->prev.
+       * z8k-tdep.c (z8k_frame_chain): Do not use ->prev.
+       * s390-tdep.c (s390_frame_chain): Do not use ->prev.
+       * rs6000-tdep.c (frame_get_saved_regs): Use rs6000_frame_chain()
+       instead of ->prev.
+
+2002-04-19  Elena Zannoni  <ezannoni@redhat.com>
+
+        Fix PR gdb/471.
+       * gdbtypes.c (init_simd_type): Rewrite using new functions.
+       (build_builtin_type_vec128): Ditto.
+       (append_composite_type_field): Fix calculation of type length in
+       union case.
+
+2002-04-19  Eli Zaretskii  <eliz@is.elta.co.il>
+
+       * config/djgpp/README: Update.
+
+       * go32-nat.c (store_register): Cast &a_tss to `char *' to avoid a
+       compiler warnings.
+
+2002-04-19  Jason Thorpe  <thorpej@wasabisystems.com>
+
+       * alpha-tdep.c (setup_arbitrary_frame): Rename...
+       (alpha_setup_arbitrary_frame): ...to this.
+       * config/alpha/tm-alpha.h (SETUP_ARBITRARY_FRAME): Update
+       for alpha_setup_arbitrary_frame.
+
+2002-04-18  Andrew Cagney  <cagney@redhat.com>
+
+       * gdbarch.sh (BREAKPOINT_FROM_PC): Return a const buffer.
+       * gdbarch.h, gdbarch.c: Regenerate.
+
+       * defs.h (breakpoint_from_pc_fn): Delete type definition.
+       * target.h (memory_breakpoint_from_pc): Update declaration.
+       * config/mcore/tm-mcore.h (mcore_breakpoint_from_p): Ditto.
+
+       * arch-utils.c (legacy_breakpoint_from_pc): Update return type.
+       * mcore-tdep.c (mcore_breakpoint_from_pc): Ditto.
+       * mem-break.c (memory_breakpoint_from_pc): Ditto.
+       * rs6000-tdep.c (rs6000_breakpoint_from_pc): Ditto.
+       * s390-tdep.c (s390_breakpoint_from_pc): Ditto
+       * xstormy16-tdep.c (xstormy16_breakpoint_from_pc): Ditto.
+       * mn10300-tdep.c (mn10300_breakpoint_from_pc): Ditto.
+       * mips-tdep.c (mips_breakpoint_from_pc): Ditto.
+       * m68hc11-tdep.c (m68hc11_breakpoint_from_pc): Ditto.
+       * ia64-tdep.c (ia64_breakpoint_from_pc): Ditto.
+       * d10v-tdep.c (d10v_breakpoint_from_pc): Ditto.
+       * arch-utils.c (legacy_breakpoint_from_pc): Ditto..
+
+       * mem-break.c (default_memory_insert_breakpoint): Make `bp' a
+       const pointer.
+       * monitor.c (monitor_insert_breakpoint): Ditto.
+       * rs6000-tdep.c (rs6000_software_single_step): Ditto for `breakp'.
+
+       * config/mcore/tm-mcore.h: Update copyright.
+       * mem-break.c: Ditto.
+       * xstormy16-tdep.c: Ditto.
+
+2002-04-18  Pierre Muller  <muller@ics.u-strasbg.fr>
+
+       * p-exp.y: Add precedence rule for '^' token.
+       This removes the shift/reduce conflicts.
+       Remove the comment concerning these shift/reduce conflicts.
+
+2002-04-18  Elena Zannoni  <ezannoni@redhat.com>
+
+       * rs6000-tdep.c (COMMON_UISA_NOFP_REGS): New macro.
+       (registers_powerpc_nofp): New register set for processors
+       without floating point unit.
+
+2002-04-18  David S. Miller  <davem@redhat.com>
+
+       * MAINTAINERS: Add myself to write-after-approval.
+
+2002-04-17  Michael Snyder  <msnyder@redhat.com>
+
+       * MAINTAINERS: Add myself as co-maintainer of testsuite/gdb.asm.
+
+2002-04-17  Andrew Cagney  <ac131313@redhat.com>
+
+       * rs6000-tdep.c (frame_initial_stack_address): Use
+       frame_register_read to read the alloca_reg.
+
+2002-04-17  Andrew Cagney  <ac131313@redhat.com>
+
+       * frame.c (find_saved_register): Find saved registers in the next
+       not prev frame.
+       Fix PR gdb/365.
+
+2002-04-17  Andrew Cagney  <ac131313@redhat.com>
+
+       * gdbarch.sh (LANG): Set to ``c''.
+
+2002-04-15  Andrew Cagney  <ac131313@redhat.com>
+
+       * PROBLEMS: Mention hppa2.0-hp-hpux10.20 compile problems.
+
+2002-04-15  Andrew Cagney  <ac131313@redhat.com>
+
+       * bcache.c: Include <stddef.h> and <stdlib.h> after "defs.h".
+       Update copyright.
+
+       * hpread.c (hpread_get_lntt): Add declaration.
+       Also fix PR gdb/391.
+
+2002-04-14  Andrew Cagney  <ac131313@redhat.com>
+
+       * acinclude.m4 (AM_PROG_CC_STDC): Import from automake 1.6.
+       * aclocal.m4, configure: Re-generate.
+       Fix PR gdb/391.
+
+2002-04-14  Elena Zannoni  <ezannoni@redhat.com>
+
+        * mi/mi-cmd-disas.c (dump_insns): Use TARGET_PRINT_INSN
+        instead of tm_print_insn.
+
+2002-04-14  Elena Zannoni  <ezannoni@redhat.com>
+
+       * ppc-bdm.c (bdm_ppc_fetch_registers): Fix typo.
+
+2002-04-14  Andrew Cagney  <ac131313@redhat.com>
+
+       * config/pa/tm-hppa.h (FRAME_CHAIN_COMBINE): Delete macro.
+       * blockframe.c (FRAME_CHAIN_COMBINE): Delete macro.
+       (get_prev_frame): Do not call FRAME_CHAIN_COMBINE.
+
+2002-04-12  Don Howard  <dhoward@redhat.com>
+
+       * cli/cli-cmds.c (init_cli_cmds): Add new user settable value:
+       max_user_call_depth.
+       (init_cmd_lists): Initialize the new value;
+       * cli/cli-script.c (execute_user_command): Limit the call depth of
+       user defined commands.  This avoids a core-dump when user commands
+       are infinitly recursive.
+
+2002-04-12  Kevin Buettner  <kevinb@redhat.com>
+
+       * ppc-tdep.h (struct gdbarch_tdep): Add new member ``lr_frame_offset''.
+       * rs6000-tdep.c (rs6000_frame_saved_pc): Use ``lr_frame_offset''
+       from tdep struct instead of DEFAULT_LR_SAVE.
+       (rs6000_gdbarch_init): Initialize ``lr_frame_offset''.
+       * config/powerpc/tm-ppc-eabi.h (DEFAULT_LR_SAVE): Delete.
+       * config/rs6000/tm-rs6000.h (DEFAULT_LR_SAVE): Delete.
+
+2002-04-12  Michael Snyder  <msnyder@redhat.com>
+
+       * Remote.c: Spelling fix.
+       * gcore.c (default_derive_heap_segment): Use bfd_section_name.
+       If no symbol found for "sbrk", try "_sbrk".
+       (make_output_phdrs): Use bfd_section_name.
+       (gcore_copy_callback): Use bfd_section_name.
+       * eval.c: Indentation fix-ups.
+       * d10v-tdep.c (d10v_make_iaddr): Make it idempotent,
+       in case it gets applied to an address that is already
+       in the instruction space.
+       * cli/cli-decode.c (help_list): Allow long lines to wrap.
+       * symfile.c: Fix indentation, long lines.
+       * source.c: White space fix-up.
+
+2002-04-12  Andrew Cagney  <cagney@redhat.com>
+
+       * defs.h (read_relative_register_raw_bytes): Delete declaration.
+       * frame.c (frame_register_read): New function.  Return non-zero on
+       success.
+       (read_relative_register_raw_bytes_for_frame): Delete.
+       (read_relative_register_raw_bytes): Delete.
+       * frame.h (frame_register_read): Declare.
+       * d30v-tdep.c: Update Copyright.  Use frame_register_read.
+       * sh-tdep.c: Ditto.
+       * infcmd.c (do_registers_info): Ditto.
+       * hppa-tdep.c: Ditto.
+       * rs6000-tdep.c: Ditto.
+       * h8500-tdep.c: Ditto.
+       * mips-tdep.c: Ditto.
+       * h8300-tdep.c: Ditto.
+       * z8k-tdep.c: Ditto.
+
+2002-04-12  Kevin Buettner  <kevinb@redhat.com>
+
+       From Jimi X <jimix@watson.ibm.com>:
+       * rs6000-tdep.c (rs6000_gdbarch_init): Use rs6000_* methods for
+       64-bit SysV ABI.
+
+2002-04-12  Kevin Buettner  <kevinb@redhat.com>
+
+       From Jimi X <jimix@watson.ibm.com>:
+       * rs6000-tdep.c (rs6000_gdbarch_init): Compute ``wordsize'' from
+       bfd info.
+
+2002-04-12  Kevin Buettner  <kevinb@redhat.com>
+
+       From Jimi X <jimix@watson.ibm.com>:
+       * rs6000-tdep.c (powerpc64, 630, rs64ii, rs64iii): Define
+       register sets for these processor variants.
+
+2002-04-11  Daniel Jacobowitz  <drow@mvista.com>
+
+       * regformats/reg-ppc.dat: Support FPSCR.
+
+2002-04-11  Kevin Buettner  <kevinb@redhat.com>
+
+       * ppc-tdep.h (struct gdbarch_tdep): Add new field ``ppc_fpscr_regnum''.
+       * ppc-bdm.c (bdm_ppc_fetch_registers, bdm_ppc_store_registers):
+       Add fpscr as an invalid/unfetchable register.
+       * ppc-linux-nat.c (ppc_register_u_addr, store_register)
+       (fetch_ppc_registers, store_ppc_registers, supply_fpregset)
+       (fill_fpregset): Add support for register fpscr.
+       (fetch_ppc_registers, store_ppc_registers, supply_gregset)
+       (fill_gregset): Account for the fact that register ``mq'' might
+       not exist.
+       * rs6000-tdep.c (PPC_UISA_SPRS): Use (unused) slot 70 for fpscr.
+       (registers_power): Add fpscr to register set at slot 71.
+       (rs6000_gdbarch_init): Account for the fact that ``mq'' doesn't
+       exist on most PPC architectures.  Initialize ppc_fpscr_regnum.
+
+2002-04-11  Michael Snyder  <msnyder@redhat.com>
+
+       * configure.in: Autoconfiscate _SYSCALL32 define for solaris.
+       * configure: Regenerate.
+       * config.in: Regenerate.
+       * acconfig.h: Add define for _SYSCALL32.
+       * core-sol2.c: Remove #define _SYSCALL32.
+       * solib-legacy.c: Remove #define _SYSCALL32.
+
+2002-04-10  Andrew Cagney  <ac131313@redhat.com>
+
+       * stack.c (select_frame): Cleanup internal error message, do not
+       use %p.
+
+2002-04-10  Andrew Cagney  <ac131313@redhat.com>
+
+       * stack.c (select_frame): Check that selected_frame and the
+       specified level are as expected.
+       * blockframe.c (get_prev_frame): Set the `level' from next_frame.
+       Update copyright.
+       * frame.h (struct frame_info): Add field `level'.  Update
+       copyright.
+       Work-in-progress PR gdb/464.
+
+2002-04-10  Andrew Cagney  <ac131313@redhat.com>
+
+       * maint.c (maint_print_section_info): Rename print_section_info.
+       (print_bfd_section_info, print_objfile_section_info): Update.
+       * inferior.h (struct gdbarch): Add opaque declaration.
+       * gdbarch.sh: Add include of "inferior.h" to gdbarch.sh.
+       * gdbarch.h: Regenerate.
+
+2002-04-10  Michal Ludvig  <mludvig@suse.cz>
+
+       * x86-64-linux-nat.c (child_resume, child_xfer_memory): Delete.
+       (PTRACE_XFER_TYPE): Moved to config/i386/nm-x86-64.h.
+       (kernel_u_size): Added.
+       * config/i386/nm-x86-64.h (CHILD_XFER_MEMORY, CHILD_RESUME): Delete.
+       (PTRACE_XFER_TYPE): Moved here from config/i386/nm-x86-64.h.
+
+2002-04-04  Jim Ingham  <jingham@apple.com>
+
+       * valarith.c (find_size_for_pointer_math): New function, either returns
+       the size for a pointer's target, returns 1 for void *, or errors for
+       incomplete types.
+       (value_add, value_sub): use find_size_for_pointer_math.
+
+2002-04-09  Daniel Jacobowitz  <drow@mvista.com>
+
+       * linux-low.c (linux_look_up_symbols): New hook.
+       (linux_target_ops): Add linux_look_up_symbols.
+       * remote-utils.c (decode_address): New function.
+       (look_up_one_symbol): New function.
+       * server.c (handle_query): Call target look_up_symbols hook.
+       * server.h (look_up_one_symbol): Add prototype.
+       * target.h (struct target_ops): Add look_up_symbols hook.
+
+2002-04-09  Andrew Cagney  <ac131313@redhat.com>
+
+       * frame.c (read_relative_register_raw_bytes_for_frame): Do not
+       override FP_REGNUM with frame->fp.  Update copyright.
+       * parse.c (num_std_regs, std_regs): Delete.
+       (target_map_name_to_register): Do not search std_regs.  Update
+       function description.
+       * parser-defs.h (num_std_regs, std_regs, struct std_regs): Delete
+       declarations.  Update copyright.
+       Fix PR gdb/251.
+
+2002-04-09  Daniel Jacobowitz  <drow@mvista.com>
+
+       * symtab.h (ALL_BLOCK_SYMBOLS): Don't dereference the pointer
+       after the last symbol in a block.
+
+2002-04-09  Pierre Muller  <muller@ics.u-strasbg.fr>
+
+       * p-exp.y (yylex): Handle also the fact that is_a_field_of_this
+       is non zero as a found symbol.
+
+2002-04-08  Andrew Cagney  <ac131313@redhat.com>
+
+       * findvar.c: Include "builtin-regs.h".
+       (value_of_register): Call value_of_builtin_reg when applicable.
+       * parse.c: Include "builtin-regs.h" and "gdb_assert.h".
+       (target_map_name_to_register): Call
+       builtin_reg_map_name_to_regnum.
+       * Makefile.in (SFILES): Add builtin-regs.c and std-regs.c.
+       (COMMON_OBS): Add builtin-regs.o and std-regs.o.
+       (builtin_regs_h): Define.
+       (builtin-regs.o): New target.
+       (findvar.o): Add $(builtin_regs_h).
+       * builtin-regs.c, builtin-regs.h: New files.
+       * std-regs.c: New file.
+       Partial fix for PR gdb/251.
+
+2002-04-08  Kevin Buettner  <kevinb@redhat.com>
+
+       * rs6000-tdep.c (rs6000_gdbarch_init): Don't set tm_print_insn;
+       it's no longer required.
+
+2002-04-08  Andrew Cagney  <ac131313@redhat.com>
+
+       * Makefile.in (gdbtk-wrapper.o): Add missing dependencies.
+
+2002-04-08  Kevin Buettner  <kevinb@redhat.com>
+
+       From Jimi X <jimix@watson.ibm.com>:
+       * rs6000-tdep.c (rs6000_software_single_step): Use
+       rs6000_breakpoint_from_pc() to fetch breakpoint instruction
+       and size.  Use target_insert_breakpoint() and
+       target_remove_breakpoint() to insert and remove breakpoints
+       instead of explicit memory reads and writes.
+
+2002-04-08  Kevin Buettner  <kevinb@redhat.com>
+
+       * config/powerpc/tm-ppc-eabi.h (ELF_OBJECT_FORMAT): Delete.
+       * rs6000-tdep.c (rs6000_push_arguments): Eliminate
+       ELF_OBJECT_FORMAT ifdef.
+
+2002-04-08  Kevin Buettner  <kevinb@redhat.com>
+
+       From Jimi X <jimix@watson.ibm.com>:
+       * rs6000-tdep.c (rs6000_gdbarch_init): Use set_gdbarch_print_insn().
+
+2002-04-08  Kevin Buettner  <kevinb@redhat.com>
+
+       From Jimi X <jimix@watson.ibm.com>:
+       * rs6000-tdep.c (rs6000_fix_call_dummy): Delete unused macro
+       definitions for TOC_ADDR_OFFSET and TARGET_ADDR_OFFSET.
+
+2002-04-07  Mark Kettenis  <kettenis@gnu.org>
+
+       * fbsd-proc.c (child_pid_to_exec_file, fbsd_find_memory_regions):
+       s/asprintf/xasprintf/.
+       (fbsd_make_corefile_notes): s/strdup/xstrdup/.
+
+2002-04-07  Andrew Cagney  <ac131313@redhat.com>
+
+       I believe Jeff Law denies responsability for this one:
+       * config/pa/hpux11w.mh (MH_CFLAGS): Add -Dvfork=fork.
+       * config/pa/hpux11.mh (MH_CFLAGS): Add -Dvfork=fork.
+       * config/pa/hpux1020.mh (MH_CFLAGS): Add -Dvfork=fork.
+       Work-around for PR gdb/366.
+
+2002-04-07  Elena Zannoni  <ezannoni@redhat.com>
+
+       * remote-e7000.c (write_small, e7000_read_inferior_memory,
+       e7000_read_inferior_memory_large, e7000_insert_breakpoint,
+       e7000_remove_breakpoint): Use paddr_nz() to print addresses.
+
+2002-04-07  Elena Zannoni  <ezannoni@redhat.com>
+
+       * sh-tdep.c (sh_fp_frame_init_saved_regs,
+       sh_nofp_frame_init_saved_regs): Use alloca() for 'where'
+       information.
+
+2002-04-07  Andrew Cagney  <ac131313@redhat.com>
+
+       * MAINTAINERS (Misc): List Daniel Jacobowitz as the GDBSERVER
+       maintainer.
+
+2002-04-07  Andrew Cagney  <ac131313@redhat.com>
+
+       * README (Reporting Bugs in GDB): Document the bug web page as the
+       prefered way of submitting bugs.
+       Fix PR gdb/402.
+
+2002-04-06  Andrew Cagney  <ac131313@redhat.com>
+
+       * gdbarch.sh (FP_REGNUM, PC_REGNUM, SP_REGNUM): Allow default of
+       -1.  Update comment.
+       * gdbarch.h, gdbarch.c: Re-generate.
+
+2002-04-07  Andreas Schwab  <schwab@suse.de>
+
+       * m68klinux-nat.c (fill_fpregset): Properly pass address of
+       buffer to regcache_collect.
+
+2002-04-06  Andrew Cagney  <ac131313@redhat.com>
+
+       * gdbarch.sh (PS_REGNUM): Add.  Document.  Default to -1.
+       * gdbarch.c, gdbarch.h: Re-generate.
+
+2002-04-06  Andrew Cagney  <ac131313@redhat.com>
+
+       * symtab.c (lookup_symtab): Remove ``const'' from ``rp''
+       declaration.  Fix -Werror.
+
+2002-04-05  Daniel Jacobowitz  <drow@mvista.com>
+
+       * gdbarch.sh (initialize_non_multiarch): Call init_gdbarch_swap.
+       * gdbarch.c: Regenerate.
+
+2002-04-05  Michael Snyder  <msnyder@redhat.com>
+
+       * breakpoint.c (clear_command): Rewrite middle section to
+       combine two loops with identical control conditions.
+       Add a cleanup to eliminate a memory leak.
+       * cli/cli-dump.c (restore_section_callback): Use paddr_nz.
+
+2002-04-05  H.J. Lu  (hjl@gnu.org)
+
+       * solib-svr4.c (bkpt_names): Add "__start".
+
+2002-04-04  Andrew Cagney  <ac131313@redhat.com>
+
+       * sparc-tdep.c (sparc_push_dummy_frame): Use GDB_TARGET_IS_SPARC64
+       as test for 64 bit target.
+
+2002-04-05  Andrew Cagney  <ac131313@redhat.com>
+
+       * h8500-tdep.c (h8500_write_fp): Delete function.
+       * dwarf2cfi.c (cfi_write_fp): Document as not used.
+       * mips-tdep.c (mips_gdbarch_init): Do not set write_fp.
+       * ia64-tdep.c (ia64_gdbarch_init): Do not set write_fp.
+       * m68hc11-tdep.c (m68hc11_gdbarch_init): Do not set write_fp.
+       * rs6000-tdep.c (rs6000_gdbarch_init): Do not set write_fp.
+       * s390-tdep.c (s390_gdbarch_init): Do not set write_fp.
+       (s390_write_fp):
+       * sh-tdep.c (sh_gdbarch_init): Do not set write_fp.
+       * x86-64-tdep.c (i386_gdbarch_init): Do not set write_fp.
+       * d10v-tdep.c (d10v_gdbarch_init): Do not set write_fp.
+       (d10v_write_fp): Delete function.
+       * inferior.h (write_fp, generic_target_write_fp): Delete
+       declarations.
+       * regcache.c (generic_target_write_fp): Delete function.
+       (write_fp): Delete function.
+       * gdbarch.sh (TARGET_WRITE_FP): Delete.
+       * gdbarch.h, gdbarch.c: Regenerate.
+       * config/v850/tm-v850.h (TARGET_WRITE_FP): Delete macro.
+       * config/sparc/tm-sp64.h (TARGET_WRITE_FP): Delete macro.
+       (sparc64_write_fp): Delete declaration.
+       * config/h8500/tm-h8500.h (TARGET_WRITE_FP): Delete macro.
+       (h8500_write_fp): Delete declaration.
+
+2002-04-04  Andrew Cagney  <ac131313@redhat.com>
+
+       * sparc-tdep.c (sparc64_write_fp): Delete.
+       (sparc_push_dummy_frame): Replace write_fp call with code to store
+       the FP directly.
+       (sparc_gdbarch_init): Do not initialize write_fp.
+
+2002-04-05  Kevin Buettner  <kevinb@redhat.com>
+
+       * rs6000-tdep.c (skip_prologue): Eliminate unused/unreachable
+       clause.
+
+2002-03-29  Jim Blandy  <jimb@redhat.com>
+
+       * stack.c (get_selected_block): Add new argument `addr_in_block',
+       used to return the exact code address we used to select the block,
+       not just the block.
+       * blockframe.c (get_frame_block, get_current_block): Same.
+       * frame.h (get_frame_block, get_current_block,
+       get_selected_block): Update declarations.
+       * linespec.c, stack.c, blockframe.c, breakpoint.c, findvar.c,
+       linespec.c, varobj.c, printcmd.c, symtab.c: Callers changed.
+
+2002-04-05  Michael Snyder  <msnyder@redhat.com>
+
+       * breakpoint.c (insert_breakpoints): Change 'hw' to 'hardware in
+       warning message.
+
+2002-04-05  J. Brobecker  <brobecker@gnat.com>
+
+       * utils.c (xfullpath): New function.
+       * defs.h (xfullpath): Add declaration.
+       * source.c (openp): Use xfullpath in place of gdb_realpath to
+       avoid resolving the basename part of filenames when the
+       associated file is a symbolic link. This fixes a potential
+       inconsistency between the filenames known to GDB and the
+       filenames it prints in the annotations.
+       * symtab.c (lookup_symtab): Use the new xfullpath function, in order
+       to be able to match a filename with either the real filename, or
+       the name of any symbolic link to this file.
+       (lookup_partial_symtab): Ditto.
+
+2002-04-04  Michael Snyder  <msnyder@redhat.com>
+
+       * breakpoint.c: Add support for hardware breakpoints in overlays.
+       (overlay_events_enabled): New state variable.
+       (insert_breakpoints): Use overlay_events_enabled to decide
+       whether to attempt to set a breakpoint at the overlay load addr.
+       Handle bp_hardware_breakpoint as well as bp_breakpoint.
+       (remove_breakpoint): Use overlay_events_enabled to decide
+       whether breakpoints need to be removed from overlay load addr.
+       Handle bp_hardware_breakpoint as well as bp_breakpoint.
+       (bpstat_stop_status): Handle bp_hardware_breakpoint in overlays.
+       (create_overlay_event_breakpoint, enable_overlay_breakpoints,
+       disable_overlay_breakpoints): Update overlay_events_enabled.
+
+2002-04-04  Daniel Jacobowitz  <drow@mvista.com>
+
+       * dwarf2read.c (struct function_range): New.
+       (cu_first_fn, cu_last_fn, cu_cached_fn): New.
+       (check_cu_functions): New.
+       (read_file_scope): Initialize global function lists.
+       Call dwarf_decode_line after processing children.
+       (read_func_scope): Add to global function list.
+       (dwarf_decode_lines): Call check_cu_functions everywhere
+       record_line is called.  Call record_line with a linenumber
+       of 0 to mark sequence ends.
+
+2002-04-04  Michal Ludvig  <mludvig@suse.cz>
+
+       * x86-64-linux-nat.c (child_xfer_memory): x86-64 ptrace() ABI
+       change sync with glibc.
+
+2002-04-03  Jim Blandy  <jimb@redhat.com>
+
+       * configure.in: Call AC_C_INLINE.
+       * configure: Regenerated.
+
+2002-04-01  Daniel Jacobowitz  <drow@mvista.com>
+
+       * rs6000-tdep.c: Change #include of "bfd/libcoff.h"
+       and "bfd/libbfd.h" to "libcoff.h" and "libbfd.h".
+
+2002-03-31  Mark Kettenis  <kettenis@gnu.org>
+
+       * NEWS: Mention gcore support on FreeBSD/i386.
+
+       * fbsd-proc.c: New file.
+       * config/i386/nm-fbsd.h (CHILD_PID_TO_EXEC_FILE): Define.
+       * config/i386/fbsd.mh (NATDEPFILES): Add gcore.o and fbsd-proc.o.
+
+       * lin-lwp.c (child_wait): Check SAVE_ERRNO instead of ERRNO in
+       while statement.
+
+2002-03-29  Jim Blandy  <jimb@redhat.com>
+
+       * cli/cli-dump.c (_initialize_cli_dump): Older GCC's tolerate
+       unescaped newlines in string literals, but newer ones don't.  So
+       escape them.
+
+2002-03-26  Michael Snyder  <msnyder@redhat.com>
+           Andrew Cagney <cagney@redhat.com>
+
+       * cli/cli-dump.c: New file.  Dump memory to file,
+       restore file to memory.
+       * cli/cli-dump.h: New file.
+       * Makefile.in: Add rules, dependencies for cli-dump.o.
+       * NEWS: Mention new commands.
+
+2002-03-28  Michael Snyder  <msnyder@redhat.com>
+
+       * symfile.c (symbol_file_add): Move test for null symbols to later.
+
+2002-03-27  Andrew Cagney  <ac131313@redhat.com>
+
+       From veksler at il.ibm.com:
+       * utils.c (gdb_realpath): If canonicalize_file_name fails, return
+       the xstrduped original path.
+       Fix PR gdb/417.
+
+2002-03-27  Michael Snyder  <msnyder@redhat.com>
+
+       * breakpoint.c (_initialize_breakpoint): Clean up help string.
+       * infcmd.c (_initialize_infcmd): Ditto.
+       * language.c (_initialize_language): Ditto.
+       * symfile.c (_initialize_symfile): Ditto.
+       * top.c (_init_main): Ditto.
+       * cli/cli-cmds.c (init_cli_cmds): Ditto.
+
+2002-03-27  Elena Zannoni  <ezannoni@redhat.com>
+
+       * rs6000-tdep.c (struct rs6000_framedata): Add fields for AltiVec
+       vector registers handling.
+       (skip_prologue): Handle new AltiVec instructions.  Fill in new
+       fields of frame data.
+       (frame_get_saved_regs): Fill in information for AltiVec registers.
+
+2002-03-27  Jim Blandy  <jimb@redhat.com>
+
+       * symtab.h (SYMBOL_INIT_MANGLED_NAME): Turn this macro's body into
+       a function; leave this macro here to invoke that function.
+       (symbol_init_mangled_name): Declaration for that function.
+       * symtab.c (symbol_init_mangled_name): New function.
+
+2002-03-27  Andrew Cagney  <ac131313@redhat.com>
+
+       * valarith.c: Replace strerror with safe_strerror.
+       * tracepoint.c: Ditto.
+       * lin-lwp.c: Ditto.
+       * go32-nat.c: Ditto.
+       * inflow.c: Ditto.
+       * gnu-nat.c: Ditto.
+
+2002-03-27  Andreas Schwab  <schwab@suse.de>
+
+       * event-top.c (command_line_handler): Remove useless if.
+
+2002-03-27  Andreas Jaeger  <aj@suse.de>
+
+       * dwarf2cfi.c: Give credit to Daniel Berlin, reformat copyright
+       comment.
+
+2002-03-27  Michal Ludvig  <mludvig@suse.cz>
+
+       * x86-64-tdep.h (X86_64_NUM_REGS, X86_64_NUM_GREGS): Delete #defines.
+       (x86_64_num_regs, x86_64_num_gregs): Added extern variables.
+       * x86-64-linux-nat.c (x86_64_regmap): Swapped RBX <> RDX, added DS, ES, FS, GS.
+       (x86_64_linux_dr_get_status, supply_gregset),
+       (fill_gregset): Changed X86_64_NUM_GREGS to x86_64_num_gregs.
+       * x86-64-tdep.c (x86_64_register_raw_size_table): Delete.
+       (x86_64_register_info_table): Add.
+       (X86_64_NUM_REGS, X86_64_NUM_GREGS): Add.
+       (x86_64_register_raw_size, x86_64_register_virtual_type),
+       (x86_64_register_name, _initialize_x86_64_tdep): Changed to reflect new
+       general x86_64_register_info_table.
+       (i386_gdbarch_init): gdbarch_register_bytes is now set
+       dynamicaly during initialization.
+       * regformats/reg-x86-64.dat: Synced with changes to registers above.
+       * gdbserver/linux-x86-64-low.c: Ditto.
+
+2002-03-27  Daniel Jacobowitz  <drow@mvista.com>
+
+       * gdbserver/server.c (main): Call target_signal_to_host_p
+       and target_signal_to_host on signals received from the remote.
+       * gdbserver/remote-utils.c (prepare_resume_reply): Call
+       target_signal_from_host on signals sent to the remote.
+       * gdbserver/server.h: Add prototypes.  Include "gdb/signals.h".
+       * gdbserver/Makefile.in: Add signals.o.  Add -I${INCLUDE_DIR}.
+
+2002-03-27  Daniel Jacobowitz  <drow@mvista.com>
+
+       * signals/signals.c: Include "server.h" in gdbserver build.
+       (target_signal_from_name): Don't use STREQ.
+       (_initialize_signals): Likewise.  Don't include function in
+       gdbserver build.
+
+2002-03-27  Daniel Jacobowitz  <drow@mvista.com>
+
+       * signals.c: Moved to...
+       * signals/signals.c: Here.
+       * Makefile (signals.o): Update.
+
+2002-03-26  Jeff Law (law@redhat.com)
+
+       * somread.c (som_symtab_read): Remove some commented out code and
+       updated related comments.  Do not set the minimal symbol table to
+       mst_solib_trampoline for ST_ENTRY symbols with SS_LOCAL scope
+       in a dynamic executable.
+       * hppa-tdep.c (find_proc_framesize): Sanely handle the case
+       where we are unable to find the minimal symbol for the given
+       PC value.
+
+2002-03-25  Jeff Law (law@redhat.com)
+
+       * linux-proc.c (read_mapping): Scan up to end of line for filename.
+
+2002-03-25  Michal Ludvig  <mludvig@suse.cz>
+
+       * x86-64-tdep.c (x86_64_skip_prologue): Rewritten from scratch.
+
+2002-03-23  Andrew Cagney  <ac131313@redhat.com>
+
+       * command.h: Update copyright.
+       (struct cmd_list_element): Replace definition with opaque
+       declaration.
+       (enum cmd_types): Document that it will eventually be moved to
+       cli/cli-decode.h
+       (CMD_DEPRECATED, DEPRECATED_WARN_USER): Delete macros.
+       (MALLOCED_REPLACEMENT): Delete macro.
+       * Makefile.in (cli_decode_h): Add $(command_h).
+       (top.o, completer.o, maint.o): Add dependency on $(cli_decode_h).
+       * top.c: Include "cli/cli-decode.h".
+       * completer.c: Include "cli/cli-decode.h".
+       * maint.c: Include "cli/cli-decode.h".
+       * cli/cli-decode.h: Include "command.h".
+       (enum command_class): Delete.
+       (enum cmd_types): Comment out.
+       (enum cmd_auto_boolean): Delete.
+       (enum var_types): Delete.
+
+2002-03-23  Andrew Cagney  <ac131313@redhat.com>
+
+       * cli/cli-decode.c: Include "gdb_assert.h".
+       (add_set_or_show_cmd): New static function.
+       (add_set_cmd): Rewrite.  Use add_set_or_show_cmd.
+       (add_show_from_set): Rewrite. Use add_set_or_show_cmd.  Don't copy
+       all fields, such as func, from the set command.
+
+2002-03-23  Andrew Cagney  <ac131313@redhat.com>
+
+       * MAINTAINERS (sh-elf): Change warning flag to -w.
+
+2002-03-23  Andrew Cagney  <cagney@redhat.com>
+
+       * defs.h (error): Add printf format attribute.
+       * thread-db.c (thread_from_lwp): Fix error format string.
+       * stack.c (parse_frame_specification): Ditto.
+       * cli/cli-decode.c (undef_cmd_error): Ditto.
+       * scm-lang.c (scm_lookup_name): Ditto.
+       * tracepoint.c (trace_error): Ditto.
+       * remote-utils.c (usage): Ditto.
+       * remote.c (compare_sections_command): Ditto.
+       Fix PR gdb/328.
+
+2002-03-22  Andrew Cagney  <ac131313@redhat.com>
+
+       * gdbtypes.c (append_composite_type_field): New function.
+       (init_composite_type): New function.
+       * gdbtypes.h (append_composite_type_field): Declare.
+       (init_composite_type): Ditto.
+
+2002-03-22  Elena Zannoni  <ezannoni@redhat.com>
+
+        * ppc-linux-tdep.c (ppc_sysv_abi_use_struct_convention): New
+        function.
+       * ppc-tdep.h (ppc_sysv_abi_use_struct_convention): Export.
+        * rs6000-tdep.c (rs6000_gdbarch_init): Use different
+        structure returning convention for SYSV ABI case, but not
+        for GNU/Linux, FreeBSD, or NetBSD.
+
+2002-03-22  Daniel Jacobowitz  <drow@mvista.com>
+
+       * symtab.h (lookup_block_symbol): Add mangled_name argument
+       to prototype.
+
+       * symmisc.c (maintenance_check_symtabs): Call lookup_block_symbol
+       with new mangled_name argument.
+       * linespec.c (decode_line_1): Likewise.
+       * valops (value_of_this): Likewise.
+       * symtab.c (lookup_transparent_type): Likewise.
+       (lookup_symbol_aux): Likewise.  Accept new mangled_name argument.
+       (lookup_symbol): If we are given a mangled name, pass it down
+       to lookup_symbol_aux.
+       (lookup_block_symbol): If we are given a mangled name to check
+       against, only return symbols which match it.
+
+2002-03-22  Christopher Faylor  <cgf@redhat.com>
+
+       * win32-nat.c (child_create_inferior): Check for proper shell to use
+       here, in case the user changes it on the fly.
+       (_initialize_inftarg): Remove shell path considerations.
+
+2002-03-21  Elena Zannoni  <ezannoni@redhat.com>
+
+       * rs6000-tdep.c (rs6000_gdbarch_init): Use correct max size value
+       for gdbarch_max_register_raw_size and max_register_virtual_size.
+       Adjust copyright year.
+
+2002-03-21  Daniel Jacobowitz  <drow@mvista.com>
+
+        * dbxread.c (process_one_symbol): Extend the first N_SLINE
+        in a function to cover the entire beginning of the function
+        as well if it does not already.
+
+2002-03-21  Tom Rix  <trix@redhat.com>
+
+       * rs6000-nat.c (rs6000_ptrace32): Renamed from ptrace32.
+       (rs6000_ptrace64): Renamed from ptrace64.
+
+2002-03-20  Martin M. Hunt  <hunt@redhat.com>
+
+       * gdbserver/remote-utils.c (remote_open): Don't call
+       getprotobyname, we're all using TCP here so just use
+       IPPROTO_TCP.
+       * gdbserver/gdbreplay.c (remote_open): Ditto.
+
+2002-03-20  Martin M. Hunt  <hunt@redhat.com>
+
+       * regcache.c (_initialize_regcache): No need to call
+       build_regcache() at this time; it gets called whenever
+       the gdbarch changes.
+
+2002-03-20  David O'Brien  <obrien@FreeBSD.org>
+
+       * sparc-nat.c:  Include sys/param.h where possible.
+
+2002-03-20  Daniel Jacobowitz  <drow@mvista.com>
+
+       Fix PR gdb/422.
+       * c-lang.c (c_create_fundamental_type): Handle FT_COMPLEX,
+       FT_DBL_PREC_COMPLEX, and FT_EXT_PREC_COMPLEX.
+       * dwarf2read.c (read_base_type): Set TYPE_TARGET_TYPE for
+       complex types.
+       * stabsread.c (rs6000_builtin_type): Likewise.
+       (read_sun_floating_type): Likewise.
+
+2002-03-19  Peter Schauer  <pes@regent.e-technik.tu-muenchen.de>
+
+       * stabsread.c (read_member_functions): Remove skip code for duplicate
+       constructor/destructor methods.  Use standard parsing for these
+       methods and just do not chain them to the list of methods after
+       parsing.
+
+2002-03-19  Alexandre Oliva  <aoliva@redhat.com>
+
+       * coffread.c: Remove redundant static declarations.  Replace
+       occurrences of `PTR' with `void *'.
+       * elfread.c, mdebugread.c, minsyms.c, mipsread.c: Likewise.
+       * top.h (quit_cover): Likewise.
+       * defs.h (catch_errors): Likewise.
+
+2002-03-18  Andrew Cagney  <ac131313@redhat.com>
+
+       * defs.h (XMALLOC): Define.
+       * gdb-events.sh (XMALLOC): Delete macro.
+       * gdb-events.c, gdb-events.h: Regenerate.
+       * gdbarch.sh (XMALLOC): Delete macro.
+       * gdbarch.c: Regenerate.
+       * serial.c (XMALLOC): Delete macro.
+       * ui-file.c (XMALLOC): Ditto.
+       * ser-unix.h (XMALLOC): Ditto.
+       * sh-tdep.c (XMALLOC): Ditto.
+       * ui-out.c (XMALLOC): Ditto.
+       * utils.c (XMALLOC): Ditto.
+       * i386-tdep.c (XMALLOC): Ditto.
+       * gdb-events.c (XMALLOC): Ditto.
+       * d10v-tdep.c (XMALLOC): Ditto.
+       * cli-out.c (XMALLOC): Ditto.
+
+       * cli-out.c, d10v-tdep.c, gdb-events.c: Update copyright.
+       * gdb-events.sh, i386-tdep.c, ser-unix.h, serial.c: Ditto.
+       * ui-file.c, ui-out.c: Ditto.
+
+2002-03-18  Andrew Cagney  <ac131313@redhat.com>
+
+       * command.h (struct cmd_list_element): Add field context.
+       (set_cmd_context, get_cmd_context): Declare.
+       * cli/cli-decode.h: Ditto.
+       * cli/cli-decode.c (get_cmd_context): New function.
+       (set_cmd_context): New function.
+       (add_cmd): Initialize context.
+       Part of fixing PR gdb/145 and PR gdb/146.
+
+2002-03-17  Andrew Cagney  <ac131313@redhat.com>
+
+       * cli/cli-decode.c (cmd_type): New function.
+       * command.h (cmd_type): Declare.
+       * infrun.c (set_schedlock_func): Call function cmd_type.
+       * kod.c (kod_set_os): Call cmd_type.
+       * cris-tdep.c (cris_version_update): Use function cmd_type.
+       (cris_mode_update, cris_abi_update): Ditto.
+
+       * command.h: (execute_cmd_post_hook): Declare.
+       (execute_cmd_pre_hook): Declare.
+       * cli/cli-script.c (clear_hook_in_cleanup): New function.
+       (execute_cmd_post_hook, execute_cmd_pre_hook): New
+       functions. Execute pre/post hook while ensuring that afterwords
+       hook_in is cleared.
+       * top.c (execute_command): Use execute_cmd_post_hook, and
+       execute_cmd_pre_hook to execute pre/post commands.
+       * infrun.c (normal_stop): Pass stop_command and not pre_hook to
+       hook_stop_stub.
+       (hook_stop_stub): Call execute_cmd_pre_hook.
+
+2002-03-17  Andrew Cagney  <ac131313@redhat.com>
+
+       * kod.c (kod_set_os): Revert previous change.  Is called by ``info
+       set'' and this leads to a core dump.  Move xstrdup of
+       operating_system to after check that it is not NULL.
+
+2002-03-17  Andrew Cagney  <ac131313@redhat.com>
+
+       * kod.c (kod_set_os): Remove unnecessary check that
+       ``command->type'' is set_cmd.
+
+       * valprint.c (set_input_radix): Use input_radix.
+       (set_output_radix): Use output_radix.
+       (set_input_radix_1, set_output_radix_1): Add FIXME - bad radix
+       isn't reverted.
+
+2002-03-16  Andrew Cagney  <ac131313@redhat.com>
+
+       * value.h (struct value): Delete field ``substring_addr''.  Change
+       aligner fields to force_doublest_align, force_longest_align,
+       force_core_addr_align and force_pointer_aligh.
+
+       * value.h (struct value): Fix typo in above change.
+
+2002-03-16  Peter Schauer  <pes@regent.e-technik.tu-muenchen.de>
+
+       * ia64-tdep.c (ia64_gdbarch_init): Call set_gdbarch_frame_args_skip,
+       to fix internal_error from ``maintenance print architecture''.
+
+2002-03-16  Peter Schauer  <pes@regent.e-technik.tu-muenchen.de>
+
+       * cp-valprint.c (cp_is_vtbl_ptr_type): Handle vtbl field type
+       for gcc versions after gcc-2.8.1.
+
+2002-03-16  Peter Schauer  <pes@regent.e-technik.tu-muenchen.de>
+
+       * eval.c (evaluate_subexp_standard): Fix setup of ``this'' pointer
+       for method resolution.  Restore adjustment of ``this'' pointer after
+       calling value_struct_elt, which was accidentally removed during the
+       HP merge.
+
+2002-03-15  Andrew Cagney  <ac131313@redhat.com>
+
+       * eval.c (evaluate_subexp_standard): Pass ``selected_frame'' to
+       value_of_register.
+       * findvar.c (value_of_register): Add ``frame'' parameter.  Pass to
+       get_saved_register.
+       * value.h (value_of_register): Update.
+
+2002-03-14  Richard Henderson  <rth@redhat.com>
+
+       * configure.in: Detect declaration for canonicalize_file_name.
+       * utils.c (canonicalize_file_name): Declare, if needed.
+       (gdb_realpath): Prefer realpath if available and usable.
+       * config.in, configure: Rebuild.
+
+2002-03-14  Richard Henderson  <rth@redhat.com>
+
+       * dwarf2read.c (read_array_type): Accept DW_FORM_data8 as
+       a constant array bound.
+
+       * MAINTAINERS: Add myself to write-after-approval.
+
+2002-03-14  Michael Snyder  <msnyder@redhat.com>
+
+       * symfile.c (syms_from_objfile): Return immediately if no syms.
+       (symbol_file_add): Return immediately if no syms.
+       (find_sym_fns): Return immediately if no syms.
+
+2002-03-13  Michal Ludvig  <mludvig@suse.cz>
+
+       * gdbserver/remote-util.c (remote_open): Print remote-side's
+       IP address when remote debugging over the network.
+
+2002-03-12  David O'Brien  <obrien@FreeBSD.org>
+
+       * config/sparc/fbsd.mh: Fix copyright.
+       * config/sparc/fbsd.mt: Likewise.
+
+2002-03-11  Richard Earnshaw  <rearnsha@arm.com>
+
+       * MAINTAINERS: Fix typo in name of gdb warnings option.
+       (x86-64): Fix formating so that this can be parsed by awk.
+
+2002-03-10  Daniel Jacobowitz  <drow@mvista.com>
+
+       * Makefile.in (defs_h): Add $(INCLUDE_DIR)/gdb/signals.h.
+       * defs.h: Include "gdb/signals.h".
+       (enum target_signal): Move to $(INCLUDE_DIR)/gdb/signals.h.
+
+2002-03-10  Michal Ludvig  <mludvig@suse.cz>
+
+       * x86-64-tdep.h (sys/reg.h, x86_64_regmap): Moved to x86-64-linux-nat.c
+       * x86-64-linux-nat.c (sys/reg.h, x86_64_regmap): Moved here
+       from x86-64-tdep.h
+
+2002-03-10  Daniel Jacobowitz  <drow@mvista.com>
+           Don Howard <dhoward@redhat.com>
+
+       * mips-tdep.c (ST0_FR): Define.
+       (mips2_fp_compat): New function, temporarily disabled.
+       (mips_read_fp_register_single): New function.
+       (mips_read_fp_register_double): New function.
+       (mips_print_register): Use them.
+       (do_fp_register_row): Likewise.
+
+2002-03-09  Andrew Cagney  <ac131313@redhat.com>
+
+       * MAINTAINERS: Add Jim Ingham and Klee Dienes to ``write after
+       approval''.
+
+2002-03-08  Peter Schauer  <pes@regent.e-technik.tu-muenchen.de>
+
+       * stabsread.c (read_member_functions): Fix is_stub test for
+       static member functions, improve comment.
+
+2002-03-07  Richard Earnshaw  <rearnsha@arm.com>
+
+       * remote-rdi.c (myprint): Replace 'PTR' with 'void *'.
+       (mywrite, mywritec, mypause, myreadc, mygets): Likewise.
+       (_initialize_remote_rdi): Use add_set_boolean_cmd to register
+       commands that set boolean values.
+       (arm_rdi_remove_breakpoint): Rewrite to avoid uninitialized warning.
+       (arm_rdi_resume): Always initialize PC.
+       (arm_rdi_open): Don't use rslt as a boolean.
+       (arm_rdi_create_inferior, arm_rdi_close, arm_rdi_resume)
+       (arm_rdi_fetch_registers, arm_rdi_store_registers)
+       (arm_rdi_xfer_memory, arm_rdi_files_info, arm_rdi_kill)
+       (arm_rdi_insert_breakpoint, arm_rdi_remove_breakpoint): Likewise.
+
+2002-03-06  Alexandre Oliva  <aoliva@redhat.com>
+
+       * configure.in (gdb_cv_bigtoc): Check for -bbigtoc on AIX.
+       * configure: Rebuilt.
+
+2002-03-06  Stephane Carrez  <Stephane.Carrez@worldnet.fr>
+
+       * m68hc11-tdep.c (_initialize_m68hc11_tdep): Don't set tm_print_insn.
+       (m68hc11_gdbarch_init): But use set_gdbarch_print_insn instead.
+
+2002-03-06  Andrew Cagney  <ac131313@redhat.com>
+
+       * cli/cli-decode.c (set_cmd_completer): New function.
+       * command.h (set_cmd_completer): Declare.
+       * cli/cli-decode.h (set_cmd_completer): Ditto.
+
+       * breakpoint.c (_initialize_breakpoint): Use set_cmd_completer.
+       * cli/cli-cmds.c (init_cli_cmds): Ditto.
+       * win32-nat.c (_initialize_inftarg): Ditto.
+       * remote-rdi.c (_initialize_remote_rdi): Ditto.
+       * proc-api.c (_initialize_proc_api): Ditto.
+       * hppa-tdep.c (_initialize_hppa_tdep): Ditto.
+       * source.c (_initialize_source): Ditto.
+       * exec.c (_initialize_exec): Ditto.
+       * solib.c (_initialize_solib): Ditto.
+       * top.c (init_main): Ditto.
+       * tracepoint.c (_initialize_tracepoint): Ditto.
+       * symfile.c (_initialize_symfile): Ditto.
+       * printcmd.c (_initialize_printcmd): Ditto.
+       * infcmd.c (_initialize_infcmd): Ditto.
+       * corefile.c (_initialize_core): Ditto.
+
+2002-03-05  Andrew Cagney  <ac131313@redhat.com>
+
+       * MAINTAINERS (Past Maintainers): Add Frank Ch. Eigler.
+
+2002-03-05  Andrew Cagney  <ac131313@redhat.com>
+
+       * MAINTAINERS: Fix Mac OS X and Objective-C/C++.
+
+2002-03-05  Andrew Cagney  <ac131313@redhat.com>
+
+       * NEWS: Update headings, 5.2 has branched.
+
+2002-03-04  Daniel Jacobowitz  <drow@mvista.com>
+
+       * gdbserver/linux-low.c (PTRACE_XFER_TYPE): Change to long.
+       (num_regs, regmap): Move inside HAVE_LINUX_USRREGS.
+       (register_addr, REGISTER_RAW_SIZE): Likewise.
+       (usr_store_inferior_registers): Use PTRACE_XFER_TYPE.
+       * gdbserver/linux-x86-64-low.c: Remove extra #endif.
+
+2002-03-03  Michal Ludvig <mludvig@suse.cz>
+
+       * MAINTAINERS (x86-64): Add myself.
+       * x86-64-tdep.c (x86_64_push_arguments): Fixed typo naregs->nregs,
+       changed value_ptr -> struct value *
+
+2002-03-01  David O'Brien  <obrien@FreeBSD.org>
+
+       * configure.host (sparc64-*-freebsd): Add.
+       * configure.tgt: Likewise.
+       * config/sparc/fbsd.mh: New file.
+       * config/sparc/fbsd.mt: Likewise.
+       * config/sparc/nm-fbsd.h: Likewise.
+       * config/sparc/tm-fbsd.h: Likewise.
+
+2002-03-01  Daniel Jacobowitz  <drow@mvista.com>
+
+       * config/djgpp/fnchange.lst: Add regformats/reg-i386-linux.dat and
+       regformats/reg-s390x.dat.
+
+2002-03-01  Andrew Cagney  <ac131313@redhat.com>
+
+       * utils.c: Add FIXME explaining true/false problem.
+
+2002-02-28  Andrew Cagney  <ac131313@redhat.com>
+
+       * MAINTAINERS (Past Maintainers): Add J.T. Conklin.
+
+2002-02-28  Michael Chastain  <mec@shout.net>
+
+       * MAINTAINERS: Fix typo: gdb.satbs -> gdb.stabs .
+
+2002-02-28  Daniel Jacobowitz  <drow@mvista.com>
+
+       * gdbserver/linux-s390-low.c: New file.
+       * regformats/reg-s390.dat: New file.
+       * regformats/reg-s390x.dat: New file.
+       * gdbserver/configure.srv: Add S/390.
+       * gdbserver/Makefile.in: Add S/390.
+       * configure.tgt: Enable gdbserver for S/390.
+
+2002-02-28  Eli Zaretskii  <eliz@is.elta.co.il>
+
+       * go32-nat.c (_initialize_go32_nat): Don't use periods in the
+       first line of the doc string for "info dos", except at the end of
+       the sentence, since the short help stops at the first period.
+
+2002-02-28  Jason Merrill  <jason@redhat.com>
+
+       * dwarf2read.c (dwarf_cfi_name): Add new codes.
+
+2002-02-27  Fred Fish  <fnf@redhat.com>
+
+       * blockframe.c (generic_fix_call_dummy): Fix obvious typo in
+       comment (dumy -> dummy).
+
+2002-02-27  Peter Schauer  <pes@regent.e-technik.tu-muenchen.de>
+
+       * symtab.c (gdb_mangle_name): Handle fully mangled v3 abi physnames.
+
+2002-02-27  Rodney Brown  <rbrown64@csc.com.au>
+
+      * utils.c (gdb_realpath): Add pathconf fallback for sco3.2v5.
+
+2002-02-27  Daniel Jacobowitz  <drow@mvista.com>
+
+       * gdbserver/acconfig.h: New file.
+       * gdbserver/i387-fp.c: New file.
+       * gdbserver/i387-fp.h: New file.
+       * gdbserver/linux-x86-64.c: New file.
+       * regformats/reg-x86-64.dat: New file.
+       * configure.tgt: Add x86_64-*-linux* gdbserver support.
+       * gdbserver/configure.srv: Add x86_64-*-linux* and regset support.
+       * gdbserver/configure.in: Add support for regsets.
+       * gdbserver/config.in: Regenerate.
+       * gdbserver/configure: Regenerate.
+       * gdbserver/Makefile.in: Likewise.  Add $(linux_low_h).
+       * gdbserver/linux-low.h: New file.
+       * gdbserver/linux-low.c: Include "linux-low.h".  Add support
+       for regsets.
+       * gdbserver/linux-arm-low.c: Include "linux-low.h".
+       * gdbserver/linux-ia64-low.c: Include "linux-low.h".
+       * gdbserver/linux-m68k-low.c: Include "linux-low.h".
+       * gdbserver/linux-mips-low.c: Include "linux-low.h".
+       * gdbserver/linux-ppc-low.c: Include "linux-low.h".
+       * gdbserver/linux-sh-low.c: Include "linux-low.h".
+       * gdbserver/linux-i386-low.c: Include "linux-low.h".  Include
+       "i387-fp.h".  Add PTRACE_GETREGS and friends.
+       * gdbserver/regcache.c (supply_register): New function.
+       (supply_register_by_name): New function.
+       (collect_register): New function.
+       (collect_register_by_name): New function.
+
+2002-02-27  Daniel Jacobowitz  <drow@mvista.com>
+
+       * gdbserver/Makefile.in (INTERNAL_CFLAGS): Remove -DGDBSERVER.
+       (config.status): Add configure.srv dependency.
+       (server_h): Add config.h dependency.
+
+2002-02-27  Daniel Jacobowitz  <drow@mvista.com>
+
+       * regformats/reg-i386-linux.dat: New file, with $orig_eax.
+       * gdbserver/Makefile.in: Add rules for reg-i386-linux.o.
+       * gdbserver/configure.srv: Change i386-*-linux* to use
+       reg-i386-linux.o.
+
+2002-02-26  Andrew Cagney  <ac131313@redhat.com>
+
+       * x86-64-tdep.c: Re-indent.  Update copyright date.
+
+2002-02-26  Andrew Cagney  <ac131313@redhat.com>
+
+       From Michal Ludvig <mludvig@suse.cz>:
+       * x86-64-tdep.c (value.h): Delete.
+       (gdb_assert.h): Include.
+       (x86_64_register_convert_to_virtual,
+       x86_64_register_convert_to_raw ): Add check which lets only
+       floating-point values to be converted.
+       (value_push): Delete.
+       (x86_64_push_arguments): Order of arguments pushed on stack fixed.
+       (i386_gdbarch_init): Number of register_bytes fixed.
+
+2002-02-26  Andrew Cagney  <ac131313@redhat.com>
+
+       * MAINTAINERS: Add x86-64 target.
+
+2002-02-26  Andrew Cagney  <ac131313@redhat.com>
+
+       * memattr.c (mem_command): Eliminate ``true'' and ``false''.
+       * osfsolib.c (solib_map_sections): Ditto.
+       * irix5-nat.c (solib_map_sections): Ditto.
+       * corelow.c (gdb_check_format): Ditto.
+       * symfile.c (symfile_bfd_open): Ditto.
+       * solib.c (solib_map_sections): Ditto.
+       Fix PR gdb/354.
+
+2002-02-26  Andrew Cagney  <ac131313@redhat.com>
+
+       * remote.c (_initialize_remote): By default, disable ``e'' and
+       ``E'' step out-of-range packets.
+
+2002-02-26  Andreas Schwab  <schwab@suse.de>
+
+       * config/m68k/tm-linux.h (FRAME_SAVED_PC): Define as
+       m68k_linux_frame_saved_pc.
+       (IN_SIGTRAMP): Define as m68k_linux_in_sigtramp instead of
+       in_sigtramp.
+       (SIGCONTEXT_PC_OFFSET): Remove.
+       * m68klinux-nat.c (m68k_linux_frame_saved_pc,
+       m68k_linux_sigtramp_saved_pc): New functions.
+       (IS_SIGTRAMP, IS_RT_SIGTRAMP): Define.
+       (SIGCONTEXT_PC_OFFSET): Moved here from config/m68k/tm-linux.h.
+       (UCONTEXT_PC_OFFSET): Define.
+       (m68k_linux_in_sigtramp): Renamed from in_sigtramp, handle both
+       non-RT and RT signal trampolines.
+
+2002-02-26  Richard Earnshaw  <rearnsha@arm.com>
+
+       * config/arm/tm-embed.h (TARGET_UPAGES): Delete.
+       (TARGET_NBPG, STACK_END_ADDR): Delete
+       (VARIABLES_INSIDE_BLOCK): Delete.
+
+2002-02-25  Andrew Cagney  <ac131313@redhat.com>
+
+       * utils.c (perror_with_name): Make string parameter constant.
+       (print_sys_errmsg): Ditto.
+       (query): Ditto.
+       * defs.h (perror_with_name): Update.
+       (print_sys_errmsg): Update.
+       (query): Update.
+
+2002-02-25  Daniel Jacobowitz  <drow@mvista.com>
+
+       From Eliot Dresselhaus <eliot@ayrnetworks.com>:
+       * gdbserver/linux-mips-low.c (cannot_fetch_register): Fix typo.
+
+2002-02-25  Peter Schauer  <pes@regent.e-technik.tu-muenchen.de>
+
+       * rs6000-nat.c (set_host_arch): Do not switch to a new architecture
+       if it already matches the current architecture from the exec file.
+       Include arch-utils.h for gdbarch_info_init prototype.
+       * Makefile.in (rs6000-nat.o): Update dependencies.
+
+2002-02-25  Eli Zaretskii  <eliz@is.elta.co.il>
+
+       * config/djgpp/djconfig.sh: Set NM=nm and CFLAGS="-g -O2" in the
+        list of exported variables.
+
+2002-02-24  Daniel Jacobowitz  <drow@mvista.com>
+
+       * gdbserver/configure.srv: New file.
+       * gdbserver/configure.in: Use configure.srv instead
+       of the host/target makefile fragments.  Set GDBSERVER_DEPFILES
+       from it.
+       * gdbserver/configure: Regenerated.
+       * gdbserver/terminal.h: New file.
+       * gdbserver/Makefile.in: Update for configure changes.  Remove
+       more unneeded include paths.
+
+2002-02-24  Andrew Cagney  <ac131313@redhat.com>
+
+       From wiz at danbala:
+       * config/sparc/tm-sp64.h: Fix grammar and typos.
+       Fix PR gdb/287.
+
+2002-02-24  Andrew Cagney  <ac131313@redhat.com>
+
+       * lin-lwp.c, thread-db.c, defs.h, cris-tdep.c: Replace ``Linux''
+       with either ``GNU/Linux'' or ``Linux kernel''.  Update copyright.
+       * m68klinux-nat.c, sparc-linux-nat.c, x86-64-linux-nat.c: Ditto.
+       * x86-64-linux-tdep.c, gregset.h, gdb_wait.h: Ditto.
+       * ia64-linux-nat.c, infrun.c, linux-proc.c: Ditto.
+       * proc-service.c, i386-linux-tdep.c, ppc-linux-tdep.c: Ditto.
+       * s390-tdep.c: Ditto.
+       * config/nm-linux.h, config/alpha/nm-linux.h: Ditto.
+       * config/alpha/tm-alpha.h, config/alpha/tm-alphalinux.h:
+       * config/alpha/xm-alphalinux.h, config/i386/nm-linux.h: Ditto.
+       * config/i386/nm-x86-64.h, config/i386/tm-linux.h: Ditto.
+       * config/m68k/tm-linux.h, config/mips/nm-linux.h: Ditto.
+       * config/mips/tm-linux.h, config/mips/xm-linux.h: Ditto.
+       * config/powerpc/tm-linux.h, config/s390/nm-linux.h: Ditto.
+       * config/s390/tm-linux.h, config/sh/tm-linux.h: Ditto.
+       * config/sparc/nm-linux.h, config/sparc/tm-linux.h: Ditto.
+       * config/sparc/tm-sp64linux.h, config/sparc/xm-linux.h: Ditto.
+       Fix PR gdb/378.
+
+2002-02-23  Andrew Cagney  <ac131313@redhat.com>
+
+       * lin-thread.c: Delete file.
+       * configure.in (gdb_cv_struct_reg_r_gs): Update comment to refer
+       to gdb_proc_service.h.
+       * configure: Re-generate.
+
+       * ocd.c (ocd_open): Do not try to open the "ocd" device.
+       * serial.c (serial_open): Delete check for "ocd".
+       Fix PR gdb/349.
+
+       * Makefile.in (linux-thread.o): Delete target.
+       * linux-thread.c: Delete file.
+
+       * config/djgpp/fnchange.lst: Rename bfd/elf32-sh64.c.  Tweak other
+       renamed SH files to be consistent.
+
+       * symtab.c (sort_search_symbols): Use xfree.
+
+2002-02-23  Richard Earnshaw  <rearnsha@arm.com>
+
+       * arm-linux-tdep.c (arm_linux_init_abi): Register
+       IN_SOLIB_CALL_TRAMPOLINE and SKIP_TRAMPOLINE_CODE
+       * config/arm/tm-linux.h (IN_SOLIB_CALL_TRAMPOLINE): Replace old
+       definition with undef, since we don't want the sysvr4 definition.
+       (SKIP_TRAMPOLINE_CODE): Likewise.
+
+2002-02-23  Andrew Cagney  <ac131313@redhat.com>
+
+       From 2002-02-22 Alfred M. Szmidt <ams@kemisten.nu>:
+
+       * configure.in: (AC_CHECK_FUNCS) Added test for
+       canonicalize_file_name Regenerated.
+        * config.in, configure: Regenerated.
+        * utils.c: (gdb_realpath) If HAVE_CANONICALIZE_FILE_NAME is
+       defined use canonicalize_file_name.
+
+2002-02-23  Michael Chastain  <mec@shout.net>
+
+       * MAINTAINERS: Remove Michael Chastain from "paper trail" list.
+
+2002-02-23  Andrew Cagney  <ac131313@redhat.com>
+
+       * README: Remove references to cygnus.com.
+       * MAINTAINERS: Change Past Maintainer addresses to ``foo at bar
+       dot com'' form.  Remove references to cygnus.com and sourceware.
+
+2002-02-23  Andrew Cagney  <ac131313@redhat.com>
+
+       From 2002-02-19 Paul Eggert <eggert@twinsun.com>:
+       * Makefile.in (VER): Change "head -1" to "sed q", since POSIX
+       1003.1-2001 no longer allows "head -1".
+       * gdb/Makefile.in (version.c): Likewise.
+       * gdb/doc/Makefile.in (GDBvn.texi): Likewise.
+       * gdb/CONTRIBUTE: Change "diff -c3" to "diff -c", which is
+       equivalent.  POSIX 1003.1-2001 no longer allows "diff -c3".
+
+2002-02-23  Andrew Cagney  <ac131313@redhat.com>
+
+       * cli/cli-decode.c (cmd_cfunc_eq): New function.
+       * command.h (cmd_cfunc_eq): Declare.
+       * cli/cli-decode.h (cmd_cfunc_eq): Ditto.
+
+       * cli/cli-cmds.h (is_complete_command): Change parameter to a
+       ``struct cmd_list_element *''.
+       * cli/cli-cmds.c (is_complete_command): Update.  Use
+       cmd_cfunc_eq.
+       * top.c (execute_command): Pass the command to
+       is_complete_command.
+       * tracepoint.c: Replace function.cfunc with cmd_cfunc_eq.
+
+2002-02-23  Andrew Cagney  <ac131313@redhat.com>
+
+       From 2002-02-20 Martin Schwidefsky <schwidefsky@de.ibm.com>:
+       * config/s390/tm-s390.h (GDB_TARGET_IS_ESAME): Use renamed
+       architecture defines.
+       * s390-tdep.c (s390_gdbarch_init): Likewise.
+
+2002-02-23  Richard Earnshaw  <rearnsha@arm.com>
+
+       * arm-linux-tdep.c (arm_linux_extract_return_value): Make static.
+       (arm_linux_push_arguments): Likewise.
+       (arm_linux_init_abi): Register them.  Also register linux-specific
+       call_dummy_words.
+       (find_minsym_and_objfile): Use strcmp, not STREQ.
+       * config/arm/tm-linux.h (CALL_DUMMY_WORDS): Delete.
+       (arm_linux_call_dummy_words): Delete declaration.
+       (EXTRACT_RETURN_VALUE, PUSH_ARGUMENTS): Delete.
+       (arm_linux_extract_return_value, arm_linux_push_arguments): Delete
+       declarations.
+       (LOWEST_PC): Delete.
+
+2002-02-23  Peter Schauer  <pes@regent.e-technik.tu-muenchen.de>
+
+       * maint.c (print_section_info): Do not prepend `0x' to filepos
+       output, it will be handled by local_hex_string_custom.
+
+2002-02-23  Richard Earnshaw  <rearnsha@arm.com>
+
+       * arm-linux-nat.c (store_newfpe_single): Use regcache_collect.
+       (store_newfpe_double, store_newfpe_extended, store_fpregister)
+       (store_register, store_regs, fill_gregset, fill_fpregset): Likewise.
+
+2002-02-22  Jim Blandy  <jimb@redhat.com>
+
+       Indicate that the bcache functions don't change the strings
+       they're passed.
+       * bcache.h (bcache, hash): Add `const' keywords to declarations.
+       * bcache.c (bcache, hash): Add `const' keywords to definitions.
+
+2002-02-22  Pierre Muller  <muller@ics.u-strasbg.fr>
+
+       * win32-nat.c (child_create_inferior): Fix create flags setting bug.
+
+2002-02-21  Christopher Faylor  <cgf@redhat.com>
+
+       * win32-nat.c (register_loaded_dll): Just use raw name when we can't
+       find the complete path to a loaded DLL.
+
+2002-02-21  Fred Fish  <fnf@redhat.com>
+
+       * dbxread.c (process_one_symbol): When finding an N_FUN symbol
+       that marks the end of the range of a function, enter a line number
+       entry that has a line number of zero and a PC offset that matches
+       the end of the function.  This starts a range of PC's for which no
+       line number information is known.
+       * symtab.c (find_pc_sect_line): If our best fit is in a range of
+       PC's for which no line number info is found (line number is zero)
+       then we didn't find any valid line information.
+       * symtab.h: Document use of zero line number entry.
+
+2002-02-21  Elena Zannoni  <ezannoni@redhat.com>
+
+       * ppc-linux-nat.c (PTRACE_GETVRREGS, PTRACE_SETVRREGS): Define.
+       (have_ptrace_getvrregs): Define for run time checks.
+       (gdb_vrregset_t): New type for Altivec register handling.
+       (fetch_register, store_register): Fetch/store altivec register
+       when needed.
+       (fetch_altivec_register, store_altivec_register): New functions.
+       (supply_vrregset, fill_vrregset): New functions.
+       (fetch_altivec_registers, store_altivec_registers): New functions.
+       (fetch_ppc_registers, store_ppc_registers): Fetch/store altivec
+       registers as well.
+
+2002-02-21  Jiri Smid  <smid@suse.cz>
+
+       * config/i386/x86-64linux.mh (NATDEPFILES): Remove x86-64-nat.o.
+
+2002-02-21  Richard Earnshaw  <rearnsha@arm.com>
+
+       * Makefile.in (armnbsd-nat.o): Update dependencies.
+       * armnbsd-nat.c (supply_gregset): New function.  Common code to
+       supply the integer register set.
+       (supply_fparegset): New function.  Similar for FPA registers.
+       (fetch_regs, fetch_fp_regs): Use them.
+       (fetch_core_registers): Likewise.
+       (fetch_elfcore_registers): New function.
+       (arm_netbsd_elfcore_fns): New core-file type specification.
+       (_initialize_arm_netbsd_nat): Register it.
+
+2002-02-21  Richard Earnshaw  <rearnsha@arm.com>
+
+       * armnbsd-nat.c: Include gdbcore.h.
+       (FETCH_INFERIOR_REGISTERS): Just error if this isn't defined.
+       (fetch_regs, fetch_fp_regs, store_regs, store_fp_regs): Add explicit
+       'void' to declaration, to shut up ARI.
+       (fetch_core_registers): Make static.  Rewrite using supply_register.
+       (arm_netbsd_core_fns): New core-file type specification.
+       (_initialize_arm_netbsd_nat): New function.
+
+2002-02-21  Christopher Faylor  <cgf@redhat.com>
+
+       * win32-nat.c (register_loaded_dll): Correctly check for invalid handle
+       value.
+
+2002-02-20  Christopher Faylor  <cgf@redhat.com>
+
+       * win32-nat.c (register_loaded_dll): Handle case where FindFirstFile
+       fails.
+
+2002-02-20  Daniel Jacobowitz  <drow@mvista.com>
+
+       * jv-exp.y (parse_number): Change type of implicit longs
+       to builtin_type_uint64.
+
+2002-02-20  Daniel Jacobowitz  <drow@mvista.com>
+
+       * gdbserver/linux-low.c (mywait): Change argument to waitpid
+       to be an integer instead of a `union wait'.
+
+2002-02-20  Daniel Jacobowitz  <drow@mvista.com>
+
+       * mips-linux-nat.c: Call the operating system GNU/Linux.
+       * mips-linux-tdep.c: Likewise.
+       * mips-tdep.c: Likewise.
+
+2002-02-20  Daniel Jacobowitz  <drow@mvista.com>
+
+       Fix PR gdb/265.
+       * jv-exp.y (parse_number): Handle 64-bit integers.
+
+2002-02-20  Daniel Jacobowitz  <drow@mvista.com>
+
+       * gdbserver/configure.in: Remove AM_PROC_CC_STDC.  Change
+       AC_STDC_HEADERS to AC_HEADER_STDC.
+       * gdbserver/configure: Regenerated.
+
+2002-02-20  Richard Earnshaw  <rearnsha@arm.com>
+
+       * arc-tdep.c (get_longjmp_target): Only compile this function if JB_PC
+       is defined.
+       * sparc-tdep.c (get_longjmp_target): Likewise.
+
+2002-02-20  Richard Earnshaw  <rearnsha@arm.com>
+
+       * News: Add news about ARM and Multi-arch.  Mention the new target
+       arm*-*-netbsd*.
+
+2002-02-19  Jim Blandy  <jimb@redhat.com>
+
+       * stabsread.c (error_type_complaint): Improve error message.
+
+2002-02-19  Daniel Jacobowitz  <drow@mvista.com>
+
+       * gdbserver/README: Update documentation.
+       * gdbserver/configure.in: Update configury to match documentation.
+       * gdbserver/Makefile.in: Likewise.
+       * gdbserver/configure: Regenerated.
+       * gdbserver/aclocal.m4: New file, generated by aclocal.
+       * gdbserver/config.in: New file, generated by autoheader.
+
+2002-02-19  Richard Earnshaw  <rearnsha@arm.com>
+
+       * config/djgpp/fnchange.lst: Add change rules for armnbsd-tdep.c and
+       armnbsd-nat.c.
+
+2002-02-19  Richard Earnshaw  <rearnsha@arm.com>
+
+       * arm-tdep.h (enum arm_float_model): New enum.
+       (struct gdbarch_tdep): Add fp_model.
+       * arm-tdep.c (arm_gdbarch_init): Set fp_model in tdep.  Defer setting
+       up floating-point conversions until we know the floating-point model
+       in use by the inferior.  Don't complain about being unable to
+       determine the ABI of the inferior when we don't have one.
+       (arm_extract_return_value): Support different floating-point models.
+       (arm_store_return_value): Likewise.
+       * armnbsd-tdep.c (arm_netbsd_aout_init_abi): Set fp_model in tdep to
+       ARM_FLOAT_SOFT.
+       (arm_netbsd_elf_init_abi): Set fp_model to ARM_FLOAT_SOFT_VFP.
+
+2002-02-19  Peter Schauer  <pes@regent.e-technik.tu-muenchen.de>
+
+       * i386-tdep.c (i386_gdbarch_init): Eliminate incorrect use
+        of ``current_gdbarch''.
+
+2002-02-19  Richard Earnshaw  <rearnsha@arm.com>
+
+       * armnbsd-nat.c : ANSIfy all function declarations.
+       (fetch_register, fetch_regs, fetch_fp_register, fetch_fp_regs): New.
+       (fetch_inferior_registers): Re-implement in terms of above.
+       (store_register, store_regs, store_fp_register, store_fp_regs): New.
+       (store_inferior_registers): Re-implement in terms of above.
+
+2002-02-19  Richard Earnshaw  <rearnsha@arm.com>
+
+       * arm-linux-nat.c: Linux -> GNU/Linux when not talking about the
+       kernel.
+       * arm-linux-tdep.c: Likewise.
+       * config/arm/tm-linux.h: Likewise.
+
+2002-02-19  Richard Earnshaw  <rearnsha@arm.com>
+
+       * configure.tgt (arm*-*-netbsd*): This variant is now fully multi-arch.
+       * config/arm/nbsd.mt (TM_FILE): Delete.
+       * config/arm/tm-nbsd.h: Delete.
+
+2002-02-19  Richard Earnshaw  <rearnsha@arm.com>
+
+       * arm-tdep.c (arm_gdbarch_init): Initialize TARGET_CHAR_SIGNED.
+       Initialize CALL_DUMMY_LENGTH.
+
+2002-02-19  Richard Earnshaw  <rearnsha@arm.com>
+
+       * armnbsd-tdep.c (arm_netbsd_aout_in_solib_call_trampoline): New
+       function.
+       (arm_netbsd_aout_init_abi): Initialize IN_SOLIB_CALL_TRAMPOLINE.
+       * config/arm/tm-nbsd.h: Don't include config/tm-nbsd.h, it only
+       defines one thing and that is incorrect for this port.
+       (IN_SOLIB_CALL_TRAMPOLINE): Delete.
+
+2002-02-18  Pierre Muller  <muller@ics.u-strasbg.fr>
+
+       * go32-nat.c: add i386-tdep.h include to import FP_REGNUM_P macro.
+
+2002-02-18  Pierre Muller  <muller@ics.u-strasbg.fr>
+
+       * win32-nat.c (display_selector): New function. Displays information
+       about the information returned by GetThreadSelectorEntry API function.
+       (display_selectors): New function. Displays the infomation of
+       the selector given as argument, or of CS, DS ans FS selectors
+       if no argument is given.
+       ( _initialize_inftarg): Add "w32" as info prefix command.
+       Add "info w32 selector" as command calling display_selectors.
+
+2002-02-19  Pierre Muller  <muller@ics.u-strasbg.fr>
+
+       * i386-tdep.c (get_longjmp_target): Fix compilation failure
+       by setting dummy values to JB_PC and JB_ELEMENT_SIZE
+       if not defined.
+
+2002-02-18  Richard Earnshaw  <rearnsha@arm.com>
+
+       * config/arm/nbsd.mt (TDEPFILES): Add solib-sunos.o.
+
+2002-02-18  Richard Earnshaw  <rearnsha@arm.com>
+
+       * arm-tdep.c (arm_set_call_dummy_breakpoint_offset): New function.
+       (arm_fix_call_dummy): Call it.
+       (arm_call_dummy_breakpoint_offset): Delete.
+       (arm_gdbarch_init): Initialize call_dummy_breakpoint_offset.
+       * config/arm/tm-arm.h (CALL_DUMMY_BREAKPOINT_OFFSET): Delete.
+
+2002-02-18  Andrew Cagney  <ac131313@redhat.com>
+
+       * gdbarch.sh (FRAME_CHAIN_VALID): Only require at level 2.
+       Default to func_frame_chain_valid.
+       * gdbarch.h, gdbarch.c: Re-generate.
+       * frame.h (FRAME_CHAIN_VALID): Delete definition.
+
+2002-02-18  Elena Zannoni  <ezannoni@redhat.com>
+
+       * ppc-linux-nat.c: Update copyright.
+       (fetch_register, store_register): Add tid parameter, don't compute
+       tid here.
+       (fetch_ppc_registers, store_ppc_registers): Add tid
+       parameter. Pass it along to callees.
+       (fetch_inferior_registers, store_inferior_registers): Compute tid
+       here, and pass it to calleed functions.
+       (fill_gregset, supply_fpregset): Clean up formatting.
+
+2002-02-18  Richard Earnshaw  <rearnsha@arm.com>
+
+       * arm-tdep.c (arm_gdbarch_init): Initialize coerce_float_to_double.
+       * config/arm/tm-arm.h (COERCE_FLOAT_TO_DOUBLE): Delete.
+
+2002-02-18  Richard Earnshaw  <rearnsha@arm.com>
+
+       * gdbarch.sh (GET_LONGJMP_TARGET): Add rule.
+       * gdbarch.c gdbarch.h: Regenerate.
+       * breakpoint.c (create_longjmp_breakpoint): Always compile this
+       function.
+       (breakpoint_reset): Test GET_LONGJMP_TARGET_P().
+       * infrun.c (GET_LONGJMP_TARGET): Delete default definition.
+       (handle_inferior_event): Test GET_LONGJMP_TARGET_P().
+
+       * arm-tdep.h (struct gdbarch_tdep): Add jb_pc and jb_elt_size fields.
+       * arm-tdep.c (arm_get_longjmp_target): New function.
+       (arm_gdbarch_init): Initialize jb_pc to -1.  If ABI handler changes
+       this to a positive value register arm_get_longjmp_target as the
+       longjmp handler.
+       * arm-linux-tdep.c (arm_get_longjmp_target): Delete.
+       (arm_linux_init_abi): Set up longjmp description in tdep.
+       * armnbsd-nat.c (get_longjmp_target): Delete.
+       * armnbsd-tdep.c (arm_netbsd_init_abi_common): Set up longjmp
+       description in tdep.
+       * config/arm/tm-nbsd.h (JB_ELEMENT_SIZE, JB_PC): Delete.
+       (get_longjmp_target): Delete declaration.
+       (GET_LONGJMP_TARGET): Delete.
+       * config/arm/tm-linux.h (arm_get_longjmp_target): Delete declaration.
+       (GET_LONGJMP_TARGET): Delete.
+
+2002-02-17  Kevin Buettner  <kevinb@redhat.com>
+
+       From Peter Schauer  <pes@regent.e-technik.tu-muenchen.de>:
+       * ia64-tdep.c (ia64_gdbarch_init): Eliminate incorrect use
+       of ``current_gdbarch''.
+
+2002-02-17  Tom Tromey  <tromey@redhat.com>
+
+       * cli/cli-cmds.c (compare_strings): New function.
+       (complete_command): Only print each unique item once.
+       * completer.h (complete_line): Declare.
+       * completer.c (complete_line): New function.
+       (line_completion_function): Use it.
+
+2002-02-16  Andrew Cagney  <ac131313@redhat.com>
+
+       * gdbarch.sh (TARGET_LONG_DOUBLE_BIT): Default to 64.
+       * gdbarch.h, gdbarch.c: Re-generate.
+
+2002-02-16  Daniel Jacobowitz  <drow@mvista.com>
+
+       * valarith.c (value_x_unop): Fix decrement; support post-decrement.
+
+2002-02-16  Daniel Jacobowitz  <drow@mvista.com>
+
+       From Peter Schauer <Peter.Schauer@Regent.E-Technik.TU-Muenchen.DE>:
+       * valops.c (value_arg_coerce): Don't take the address of a reference
+       to convert an argument to a reference.
+
+2002-02-15  Christopher Faylor  <cgf@redhat.com>
+
+       * win32-nat.c (get_image_name): New function.
+       (handle_load_dll): Use get_image_name function.
+       (get_child_debug_event): Avoid registering debug events until possibly
+       execed process is started.
+       (child_create_inferior): Allow invocation via shell so that command
+       line redirection, etc.  works ok.
+       (_initialize_inftarg): Add new command: "set shell" to control whether
+       a shell is used to start a process.
+
+2002-02-15  Daniel Jacobowitz  <drow@mvista.com>
+
+       * gdbserver/linux-mips-low.c (cannot_fetch_register): Use find_regno
+       instead of find_register_by_number.
+       (cannot_store_register): Likewise.
+
+2002-02-14  Pierre Muller  <muller@ics.u-strasbg.fr>
+
+       * dwarf2read.c: Replace fprintf (stderr, ...) by
+       fprintf_unfiltered (gdb_stderr, ...).
+
+2002-02-15  Daniel Jacobowitz  <drow@mvista.com>
+
+       * gdbserver/gdbserver.1: Document --attach.
+
+2002-02-15  Richard Earnshaw  <rearnsha@arm.com>
+
+       * arm-tdep.h (struct gdbarch_tdep): Add fields for breakpoint
+       descriptions.
+       * arm-tdep.c (arm_default_arm_le_breakpoint)
+       (arm_default_arm_be_breakpoint, arm_default_thumb_le_breakpoint)
+       (arm_default_thumb_be_breakpoint): New.  Initialize them from
+       traditional breakpoint defines.
+       (arm_breakpoint_from_pc): Use new gdbarch_tdep entries.
+       (arm_gdbarch_init): Initialize new breakpoint variables.
+       * arm-linux-tdep.c (arm_linux_arm_le_breakpoint): New.
+       (arm_linux_init_abi): Initialize linux-specific breakpoint.
+       * armnbsd-tdep.c (arm_nbsd_arm_le_breakpoint): New.
+       (arm_netbsd_aout_init_abi, arm_netbsd_elf_init_abi): Split common
+       code out to ...
+       (arm_netbsd_init_abi_common): ... here; new function.
+       * config/arm/tm-arm.h (ARM_LE_BREAKPOINT, ARM_BE_BREAKPOINT)
+       (THUMB_LE_BREAKPOINT, THUMB_BE_BREAKPOINT): Delete.
+       * config/arm/tm-linux.h (ARM_LE_BREAKPOINT): Delete.
+       * config/arm/tm-nbsd.h (ARM_LE_BREAKPOINT): Delete.
+
+2002-02-15  Richard Earnshaw  <rearnsha@arm.com>
+
+       * arm-tdep.h (enum arm_abi): New enum.
+       (struct gdbarch_tdep): New structure.
+       (LOWEST_PC): Provide a default.
+       (arm_gdbarch_register_os_abi): Declare new function.
+       * arm-tdep.c (arm_abi_names): New array.
+       (process_note_abi_tag_sections): New function.
+       (get_elfosabi): New function.
+       (arm_gdbarch_register_os_abi): New function.
+       (arm_gdbarch_init): Try to determine the ABI of the inferior.  If
+       support for that ABI has been built in, then call the appropriate
+       configuration routine.  Use gdbarch_num_regs() to get the number
+       of registers.
+       (arm_dump_tdep): New function.
+       (arm_init_abi_eabi_v1, arm_init_abi_eabi_v2, arm_init_abi_apcs): New
+       place-holder functions.
+       (_initialize_arm_tdep): Register them.
+       * config/arm/tm-arm.h (LOWEST_PC): Delete.
+
+       * armnbsd-tdep.c: New file.
+       * Makefile.in (armnbsd-tdep.o): Add dependencies.
+       * config/arm/nbsd.mt (TDEPFILES): Add it.
+       * config/arm/tm-nbsd.h (LOWEST_PC): Delete.
+
+       * armnbsd-nat.c: Include regcache.h.
+       * Makefile.in (armnbsd-nat.o): Update dependency list.
+
+       * arm-tdep.c (arm_get_next_pc): Use printf_filtered for error message.
+
+2002-02-14  Daniel Jacobowitz  <drow@mvista.com>
+
+       * gdbserver/Makefile.in: Fix typos in target rules.
+
+2002-02-14  Daniel Jacobowitz  <drow@mvista.com>
+
+       Fix part of PR gdb/267.
+       * linespec.c (find_methods): Handle constructors specially for now.
+
+2002-02-14  Corinna Vinschen  <vinschen@redhat.com>
+
+       * arm-tdep.c (arm_push_arguments): Eliminate special float type
+       handling.
+       * config/arm/tm-arm.h (COERCE_FLOAT_TO_DOUBLE): Define to call
+       standard_coerce_float_to_double().
+
+2002-02-14  Christopher Faylor  <cgf@redhat.com>
+
+       * config/i386/xm-cygwin.h: Revert inadvertent reinclusion of
+       GDBINIT_FILENAME.
+
+2002-02-14  Elena Zannoni  <ezannoni@redhat.com>
+
+       * rs6000-tdep.c (rs6000_gdbarch_init): Don't call
+       find_variant_by_name, because it confuses the multiarch
+       framework. Return NULL if there isn't an architecture with the
+       user supplied name, instead of forcing a different one without
+       recording the change with the multiarch machinery.
+       (find_variant_by_name): Delete.
+
+2002-02-14  Peter Schauer  <pes@regent.e-technik.tu-muenchen.de>
+
+       * config/i386/i386sol2.mh (NATDEPFILES): Add i387-nat.o, needed by
+       i386v4-nat.o now. Add gcore.o, Solaris x86 supports gcore.
+
+2002-02-13  Martin M. Hunt  <hunt@redhat.com>
+
+       * stack.c (print_frame_info_base): When calling
+       print_frame_info_listing_hook, set current_source_symtab.
+
+2002-02-14  Daniel Jacobowitz  <drow@mvista.com>
+
+       * gdbserver/Makefile.in: Add regformats directory to INCLUDE_CFLAGS,
+       and remove unused $(INCLUDE_DIR).
+       Add regcache.c to OBS.
+       Add generated register protocol files to clean target.
+       Update dependencies for new objects, obsolete old target code.
+
+       * gdbserver/linux-low.c: Remove all platform-specific code to
+       new files.  Remove various dead code.  Update to use regcache
+       functionality.
+       * gdbserver/remote-utils.c (fromhex): Add return statement
+       to quiet warning.
+       (putpkt): Dynamically allocate buf2 because PBUFSIZ is no longer
+       constant.
+       (input_interrupt): Add integer parameter to match prototype
+       of a signal handler.
+       (outreg): Use register_data ().
+       (prepare_resume_reply): Use gdbserver_expedite_regs.
+       * gdbserver/server.c (main): Dynamically allocate own_buf because
+       PBUFSIZ is no longer constant.  Use registers_to_string () and
+       registers_from_string ().
+       * gdbserver/server.h: No longer include "defs.h".  Add prototypes
+       for error (), fatal (), and warning ().  Update definition of
+       PBUFSIZ to use regcache functionality.  Add include guard.
+       * gdbserver/utils.c (fatal): Add missing ``const''.
+       (warning): New function.
+
+       * regformats/regdat.sh: Include "regcache.h" in generated files.
+       Provide init_registers () function.
+       * regformats/regdef.h: Add prototype for set_register_cache ().
+       Add include guard.
+
+       * gdbserver/linux-arm-low.c: New file.
+       * gdbserver/linux-i386-low.c: New file.
+       * gdbserver/linux-ia64-low.c: New file.
+       * gdbserver/linux-m68k-low.c: New file.
+       * gdbserver/linux-mips-low.c: New file.
+       * gdbserver/linux-ppc-low.c: New file.
+       * gdbserver/linux-sh-low.c: New file.
+
+       * gdbserver/regcache.c: New file.
+       * gdbserver/regcache.h: New file.
+
+       * gdbserver/low-linux.c: Removed obsolete file.
+
+2002-02-14  Daniel Jacobowitz  <drow@mvista.com>
+
+       * config/arm/linux.mt: Update GDBSERVER_DEPFILES.
+       * config/i386/linux.mt: Likewise.
+       * config/ia64/linux.mt: Likewise.
+       * config/m68k/linux.mh: Likewise.
+       * config/powerpc/linux.mh: Likewise.
+       * config/mips/linux.mt: Likewise.
+
+       * config/sh/linux.mt: Add GDBSERVER_DEPFILES.
+
+       * config/i386/i386lynx.mh: Mark gdbserver variables
+       as (currently) obsolete for this target.
+       * config/i386/nbsd.mt: Likewise.
+       * config/i386/nbsdelf.mt: Likewise.
+       * config/m32r/m32r.mt: Likewise.
+       * config/m68k/m68klynx.mh: Likewise.
+       * config/m68k/nbsd.mt: Likewise.
+       * config/m68k/sun3os4.mh: Likewise.
+       * config/mips/vr5000.mt: Likewise.
+       * config/ns32k/nbsd.mt: Likewise.
+       * config/pa/hppabsd.mh: Likewise.
+       * config/pa/hppaosf.mh: Likewise.
+       * config/powerpc/nbsd.mt: Likewise.
+       * config/rs6000/rs6000lynx.mh: Likewise.
+       * config/s390/s390.mt: Likewise.
+       * config/s390/s390x.mt: Likewise.
+       * config/sparc/sparclynx.mh: Likewise.
+       * config/sparc/sun4os4.mh: Likewise.
+       * config/i386/x86-64linux.mt: Likewise.
+       * config/sparc/linux.mh: Likewise.
+
+2002-02-14  Daniel Jacobowitz  <drow@mvista.com>
+
+       * configure.tgt: Configure gdbserver only for known working
+       targets.  Set ${build_gdbserver} instead of modifying ${configdirs}.
+       * configure.in: Check ${build_gdbserver}.  Put gdbserver/ into
+       SUBDIRS if it is configured.  Update comment for ${nativefile}.
+       * configure: Regenerated.
+
+2002-02-13  Michael Snyder  <msnyder@redhat.com>
+
+       * config/i386/i386v42mp.mh: Add gcore.o to NATDEPFILES.
+
+       * gcore.c (gcore_command): Use gcore_default_target instead of NULL.
+       (default_gcore_mach): Just return 0, work around a problem in bfd.
+       (default_gcore_target): OK to return NULL if exec_bfd is null.
+       (make_mem_sec): Use a cast, avoid a warning.
+
+       * procfs.c (find_memory_regions_callback): Use a cast instead of
+       calling host_pointer_to_address (which complains if
+       sizeof (host pointer) != sizeof (target pointer)).
+       (procfs_make_note_section): Avoid overflow in psargs string.
+
+       * procfs.c (procfs_make_note_section): Make the default
+       implementation return an error.
+
+2002-02-13  Rodney Brown  <rbrown64@csc.com.au>
+
+       * procfs.c (procfs_make_note_section): Provide a default definition
+       (for alpha-dec-osf4.0f). Fix typos.
+
+2002-02-13  Elena Zannoni  <ezannoni@redhat.com>
+
+       * linux-proc.c: Add include of regcache.h.
+       * Makefile.in (linux-proc.o): Add dependency on regcache.h.
+
+2002-02-13  Andrew Cagney  <ac131313@redhat.com>
+
+       From 2002-01-18 Greg McGary <greg@mcgary.org>:
+       * memattr.c (create_mem_region): Disallow useless empty region.
+       Regions are half-open intervals, so allow [A..B) [B..C) as
+       non-overlapping.
+
+2002-02-13  Michael Chastain <mec@shout.net>
+
+       * defs.h: Kill CONST_PTR.
+       * c-lang.h (c_builtin_types): Change CONST_PTR to simple "const".
+       * c-lang.c (c_builtin_types): Likewise.
+       * ch-lang.c (ch_builtin_types): Likewise.
+       * f-lang.c (f_builtin_types): Likewise.
+       * language.c (unknown_builtin_types): Likewise.
+       * m2-lang.c (m2_builtin_types): Likewise.
+       * p-lang.c (pascal_builtin_types): Likewise.
+       * scm-lang.c (c_builtin_types): Likewise.
+
+2002-02-13  Keith Seitz  <keiths@redhat.com>
+
+       * arm-tdep.h (arm_get_next_pc): Add declaration.
+
+2002-02-13  Richard Earnshaw  <rearnsha@arm.com>
+
+       * arm-tdep.c (arm_use_struct_convention): Make static.  Move to be
+       with other related struct-returning functions.
+       (arm_extract_struct_value_address): New function.
+       (arm_gdbarch_init): Initialize the above in multi-arch vector.  Also
+       initialize float_format, double_format and long_double_format as
+       appropriate to the endianness of the target.
+       * config/arm/tm-arm.h (TARGET_DOUBLE_FORMAT): Delete.
+       (arm_use_struct_convention): Delete declaration.
+       (USE_STRUCT_CONVENTION, EXTRACT_STRUCT_VALUE_ADDRESS): Delete.
+
+2002-02-13  Keith Seitz  <keiths@redhat.com>
+
+        * defs.h (core_addr_to_string_nz): New function.
+
+2002-02-13  Mark Kettenis  <kettenis@gnu.org>
+
+       Apply missing bits of 2002-01-15 patch.
+       * i386v4-nat.c (supply_fpregset): Use i387_supply_fsave.
+       (fill_fpregset): Use i387_fill_fsave.
+
+2002-02-12  Keith Seitz  <keiths@redhat.com>
+
+       * utils.c (core_addr_to_string): Use phex instead of phex_nz.
+       (core_addr_to_string_nz): New function.
+
+2002-02-11  Richard Earnshaw  <rearnsha@arm.com>
+
+       * arm-linux-nat.c: Really include arm-tdep.h.
+       * config/arm/tm-linux.h (struct type, struct value): Declare.
+
+2002-02-11  Michael Snyder  <msnyder@redhat.com>
+
+       * procfs.c: Include elf-bfd.h (for elfcore_write functions).
+       (gcore section): Ifdef for Solaris and Unixware only.
+       (procfs_do_thread_registers): Unixware needs one lwpstatus
+       per thread (not one prstatus or pstatus).
+       (procfs_make_note_section): Iterate only over kernel threads (lwps),
+       not over all gdb threads.  For unixware, call elfcore_write_pstatus
+       once before iterating over threads.
+
+2002-02-11  Richard Earnshaw  <rearnsha@arm.com>
+
+       * arm-tdep.h: New file.
+       * arm-tdep.c: Include arm-tdep.h.
+       (arm_addr_bits_remove, arm_smash_text_address, arm_saved_pc_after_call)
+       (arm_skip_prologue, arm_call_dummy_words, arm_fix_call_dummy)
+       (arm_print_float_info, arm_register_type, convert_to_extended)
+       (arm_elf_make_msymbols_special, arm_coff_make_msymbol_special)
+       (arm_extract_return_value, arm_register_name): Make static.
+       (arm_software_single_step): Similarly.  Fix types in declaration.
+       (arm_register_byte, arm_register_raw_size, arm_register_virtual_size)
+       (arm_store_return_value, arm_store_struct_return): New functions.
+       (arm_gdbarch_init): Register the above functions.  Also register
+       call_dummy_start_offset, sizeof_call_dummy_words,
+       function_start_offset, inner_than, decr_pc_after_break, fp_regnum,
+       sp_regnum, pc_regnum, register_bytes, num_regs, max_register_raw_size,
+       max_register_virtual_size, register_size.  Set up
+       prologue_cache.saved_regs here, rather than ...
+       (_initialize_arm_tdep): ... here.
+       * config/arm/tm-arm.h (struct type, struct value): Delete forward
+       declarations.
+       (arm_addr_bits_remove, arm_smash_text_address, arm_saved_pc_after_call)
+       (arm_skip_prologue, arm_call_dummy_words, arm_fix_call_dummy)
+       (arm_print_float_info, arm_register_type, convert_to_extended)
+       (arm_elf_make_msymbols_special, arm_coff_make_msymbol_special)
+       (arm_extract_return_value, arm_register_name): Delete declarations.
+       (SMASH_TEXT_ADDRESS, ADDR_BITS_REMOVE, FUNCTION_START_OFFSET)
+       (SKIP_PROLOGUE, SAVED_PC_AFTER_CALL, INNER_THAN, BREAKPOINT_FROM_PC)
+       (DECR_PC_AFTER_BREAK, PRINT_FLOAT_INFO, REGISTER_SIZE, NUM_REGS)
+       (REGISTER_NAME, REGISTER_BYTES, REGISTER_BYTE, REGISTER_RAW_SIZE)
+       (REGISTER_VIRTUAL_SIZE, MAX_REGISTER_RAW_SIZE)
+       (MAX_REGISTER_VIRTUAL_SIZE, REGISTER_VIRTUAL_TYPE, STORE_STRUCT_RETURN)
+       (EXTRACT_RETURN_VALUE, STORE_RETURN_VALUE, CALL_DUMMY_WORDS)
+       (SIZEOF_CALL_DUMMY_WORDS, CALL_DUMMY_START_OFFSET, FIX_CALL_DUMMY)
+       (SOFTWARE_SINGLE_STEP_P, SOFTWARE_SINGLE_STEP)
+       (ELF_MAKE_MSYMBOL_SPECIAL, COFF_MAKE_MSYMBOL_SPECIAL) Delete.
+       (arm_pc_is_thumb, arm_pc_is_thumb_dummy, thumb_get_next_pc)
+       (arm_get_next_pc): No-longer static -- these are needed by the RDI
+       interface.
+       * arm-linux-nat.c arm-linux-tdep.c armnbsd-nat.c: Include arm-tdep.h.
+       * remote-rdi.c remote-rdp.c: Likewise.
+       * Makefile.in (arm-linux-nat.o, arm-linux-tdep.o arm-tdep.o)
+       (armnbsd-nat.o, remote-rdi.o, remote_rdp.o): Update dependencies.
+       * config/arm/tm-nbsd.h (SOFTWARE_SINGLE_STEP_P): Delete bogus
+       definition.
+
+       * arm-tdep.h (ARM_A1_REGNUM, ARM_A4_REGNUM, ARM_AP_REGNUM)
+       (ARM_SP_REGNUM, ARM_LR_REGNUM, ARM_PC_REGNUM, ARM_F0_REGNUM)
+       (ARM_F3_REGNUM, ARM_F7_REGNUM, ARM_FPS_REGNUM, ARM_PS_REGNUM): Renamed
+       from non-ARM_ prefixed definitions.
+       * arm-tdep.c armnbsd-nat.c arm-linux-nat.c arm-linux-tdep.c: Update
+       all uses of above.
+       * remote-rdi.c remote-rdp.c: Likewise.
+       * arm-linux-nat.c (ARM_CPSR_REGNUM): Renamed from CPSR_REGNUM.
+
+2002-02-11  Richard Earnshaw  <rearnsha@arm.com>
+
+       * arm-tdep.c (arm_frameless_function_invocation)
+       (arm_frame_args_address, arm_frame_locals_address, arm_frame_num_args)
+       (arm_frame_chain, arm_init_extra_frame_info, arm_frame_saved_pc)
+       (arm_read_fp, arm_frame_init_saved_regs, arm_push_dummy_frame)
+       (arm_pop_frame, arm_get_next_pc): Make static.
+       (arm_gdbarch_init): Register above in gdbarch structure.
+       (arm_read_fp): Renamed from arm_target_read_fp.
+       (arm_pc_is_thumb, arm_pc_is_thumb_dummy): Make static.
+       * config/arm/tm-arm.h (arm_frameless_function_invocation)
+       (arm_frame_args_address, arm_frame_locals_address, arm_frame_num_args)
+       (arm_frame_chain, arm_init_extra_frame_info, arm_frame_saved_pc)
+       (arm_target_read_fp, arm_frame_init_saved_regs, arm_push_dummy_frame)
+       (arm_pop_frame, arm_get_next_pc, arm_pc_is_thumb)
+       (arm_pc_is_thumb_dummy): Delete declarations.
+       (INIT_EXTRA_FRAME_INFO, TARGET_READ_FP, FRAME_CHAIN)
+       (FRAMELESS_FUNCTION_INVOCATION, FRAME_SAVED_PC, FRAME_ARGS_ADDRESS)
+       (FRAME_LOCALS_ADDRESS, FRAME_NUM_ARGS, FRAME_ARGS_SKIP)
+       (FRAME_INIT_SAVED_REGS, PUSH_DUMMY_FRAME, POP_FRAME): Delete.
+
+2002-02-10  Daniel Jacobowitz  <drow@mvista.com>
+
+       * symtab.c (compare_search_syms): New function.
+       (sort_search_symbols): New function.
+       (search_symbols): Sort symbols after searching rather than
+       before.
+
+2002-02-10  Andrew Cagney  <ac131313@redhat.com>
+
+       * NEWS: Linux -> GNU/Linux.
+
+2002-02-10  Andrew Cagney  <ac131313@redhat.com>
+
+       * gdbarch.sh: For for level one methods, disallow a definition
+       when partially multi-arched.  Add comments explaining rationale.
+       * gdbarch.h: Re-generate.
+
+2002-02-10  Andrew Cagney  <ac131313@redhat.com>
+
+       * gdbarch.sh (EXTRA_STACK_ALIGNMENT_NEEDED): Don't require when
+       multi-arch partial.
+
+2002-02-10  Andrew Cagney  <ac131313@redhat.com>
+
+       * gdbarch.sh: Map LEVEL onto a symbolic GT_LEVEL.  Exit on bad
+       field.  Use diff -u.
+       * gdbarch.c: Re-generate.
+
+2002-02-10  Andrew Cagney  <ac131313@redhat.com>
+
+       * config/mips/tm-mips.h (CALL_DUMMY_LOCATION): Delete.
+       * gdbarch.sh (PUSH_RETURN_ADDRESS): Don't require when multi-arch
+       partial.
+
+2002-02-10  Andrew Cagney  <ac131313@redhat.com>
+
+       * gdbarch.sh (REGISTER_CONVERTIBLE): Don't require when
+       multi-arch partial.
+       (PUSH_ARGUMENTS): Switch to using predefault.
+       * gdbarch.c: Regenerate.
+
+2002-02-10  Andrew Cagney  <ac131313@redhat.com>
+
+       * valops.c (PUSH_ARGUMENTS): Delete definition.
+       * gdbarch.sh (PUSH_ARGUMENTS): Don't require when multi-arch
+       partial.  Default to default_push_arguments.
+       * gdbarch.h, gdbarch.c: Regenerate.
+
+2002-02-09  Andrew Cagney  <ac131313@redhat.com>
+
+       * defs.h (throw_exception): Rename return_to_top_level.  Update
+       comments.
+       * utils.c (error_stream, internal_verror, quit): Ditto.
+       * top.c (throw_exception, catcher): Ditto.
+       * sparclet-rom.c (sparclet_load): Ditto.
+       * remote.c (interrupt_query, minitelnet): Ditto.
+       * remote-sds.c (interrupt_query): Ditto.
+       * remote-mips.c (mips_error, mips_kill): Ditto.
+       * ocd.c (interrupt_query): Ditto.
+       * monitor.c (monitor_interrupt_query): Ditto.
+       * m3-nat.c (suspend_all_threads, thread_resume_command): Ditto.
+       * target.h: Update comment.
+
+       * m3-nat.c, ocd.c, sparclet-rom.c: Update copyright.
+
+2002-02-09  Andrew Cagney  <ac131313@redhat.com>
+
+       * gdbarch.sh (TARGET_LONG_DOUBLE_FORMAT): Default to
+       default_double_format.
+       * gdbarch.h, gdbarch.c: Re-generate.
+       * findvar.c (floatformat_unknown): Delete variable definition.
+       * doublest.h (floatformat_unknown): Delete variable declaration.
+
+2002-02-09  Jim Blandy  <jimb@redhat.com>
+
+       * stabsread.c (read_type): Add code to parse Sun's syntax for
+       prototyped function types.
+
+2002-02-09  Andrew Cagney  <ac131313@redhat.com>
+
+       * Makefile.in (SUBDIR_CLI_INITS): Set to SUBDIR_CLI_SRCS.
+       (SUBDIR_MI_INITS): Set to SUBDIR_MI_SRCS.
+
+2002-02-09  Peter Schauer  <pes@regent.e-technik.tu-muenchen.de>
+
+       * xcoffsolib.c (_initialize_xcoffsolib): Renamed from
+       _initialize_solib.  Fixes name clash with solib.c:_initialize_solib,
+       now _initialize_xcoffsolib gets called again and overrides the
+       commands from solib.c in a native configuration.
+
+2002-02-09  Mark Kettenis  <kettenis@gnu.org>
+
+       * doublest.c (store_typed_floating): Don't try to return a value.
+       Fixes PR gdb/290.
+
+2002-02-08  Jim Blandy  <jimb@redhat.com>
+
+       * c-typeprint.c (c_type_print_varspec_suffix): If a function type
+       is prototyped and has no arguments, print its argument list as
+       `(void)'.
+
+2002-02-08  Chris Demetriou  <cgd@broadcom.com>
+
+       * MAINTAINERS (write-after-approval): Add myself.
+       (paper-trail): I've escaped!
+
+2002-02-08  Christopher Faylor  <cgf@redhat.com>
+
+       * win32-nat.c (cygwin_pid_to_str): Revert 2002-02-08 change xasprintf
+       changes.
+       (_initialize_check_for_gdb_ini): Ditto.
+
+2002-02-08  Martin M. Hunt  <hunt@redhat.com>
+
+       * win32-nat.c (cygwin_pid_to_str): Fix typo.
+       xaprintf -> xasprintf.
+
+2002-02-08  Pierre Muller  <muller@ics.u-strasbg.fr>
+
+       * win32-nat.c: Remove use of printf and sprintf functions.
+
+2002-02-08  Richard Earnshaw  <rearnsha@arm.com>
+
+       * arm-tdep.c (arm_frame_chain_valid): Make static.
+       (arm_push_arguments): Likewise.
+       (arm_gdbarch_init): New function.
+       (_initialize_arm_tdep): Call it.
+       * config/arm/tm-arm.h (GDB_MULTI_ARCH): Set to 1.
+       (TARGET_DOUBLE_FORMAT): Test TARGET_BYTE_ORDER, not target_byte_order.
+       (FRAME_CHAIN_VALID): Delete.
+       (arm_frame_chain_valid): Delete declaration.
+       (PUSH_ARGUMENTS): Delete.
+       (arm_push_arguments): Delete declaration.
+       (CALL_DUMMY_P): Delete.
+
+2002-02-08  Andrew Cagney  <ac131313@redhat.com>
+           Corinna Vinschen  <vinschen@redhat.com>
+
+       * gdbtypes.c (build_gdbtypes): Disable setting a specific float format
+       on builtin float types.
+
+2002-02-08  Daniel Jacobowitz  <drow@mvista.com>
+
+       * utils.c: Include <curses.h> before "bfd.h".
+       * tui/tui-hooks.c: Likewise.
+       * tui/tui.c: Likewise.
+       * tui/tuiCommand.c: Likewise.
+       * tui/tuiData.c: Likewise.
+       * tui/tuiDataWin.c: Likewise.
+       * tui/tuiDisassem.c: Likewise.
+       * tui/tuiGeneralWin.c: Likewise.
+       * tui/tuiIO.c: Likewise.
+       * tui/tuiLayout.c: Likewise.
+       * tui/tuiRegs.c: Likewise.
+       * tui/tuiSource.c: Likewise.
+       * tui/tuiSourceWin.c: Likewise.
+       * tui/tuiStack.c: Likewise.
+       * tui/tuiWin.c: Likewise.
+
+2002-02-07  Elena Zannoni  <ezannoni@redhat.com>
+
+       * sh-tdep.c (sh_nofp_frame_init_saved_regs): Extend where[] array
+       to include space for pseudoregs as well. Update loops accordingly.
+       (sh_fp_frame_init_saved_regs): Ditto.
+       (sh_init_extra_frame_info, sh_pop_frame): Split long lines.
+
+2002-02-07  Andrew Cagney  <ac131313@redhat.com>
+
+       * MAINTAINERS: Andreas Schwab is GNU/Linux m68k maintainer.
+       Add Richard Earnshaw to Arm maintainers.
+
+2002-02-07  Andrew Cagney  <ac131313@redhat.com>
+
+       * defs.h (warning_begin): Delete declaration.
+
+       * config/powerpc/tm-ppcle-eabi.h (TARGET_BYTE_ORDER_DEFAULT):
+       Delete macro.
+
+2002-02-07  Michael Snyder  <msnyder@redhat.com>
+
+       * solib-legacy.c (legacy_svr4_fetch_link_map_offsets):
+       Logic bug, remove misplaced else.
+
+2002-02-07  Klee Dienes  <klee@apple.com>
+
+       * fork-inferior.c (fork_inferior): Add '!' to the list of
+       characters that need to be quoted when building a string for the
+       shell.  Quote '!' specifically with a backslash, since CSH chokes
+       when trying to evaluate "str!str".
+
+2002-02-06  Nick Clifton  <nickc@cambridge.redhat.com>
+
+       * rdi-share/host.h: Only provide a typedef for bool if it is not
+       defined.
+
+2002-02-04  Michael Snyder  <msnyder@redhat.com>
+
+       * breakpoint.h (enum bptype): Add new overlay event bp type.
+       (enable_overlay_breakpoints, disable_overlay_breakpoints): Export.
+
+       * breakpoint.c (create_internal_breakpoint): New function.
+       (internal_breakpoint_number): Moved into create_internal_breakpoint.
+       (create_longjmp_breakpoint): Use create_internal_breakpoint.
+       (create_thread_event_breakpoint): Ditto.
+       (create_solib_event_breakpoint): Ditto.
+       (create_overlay_event_breakpoint): New function.
+       (enable_overlay_breakpoints, disable_overlay_breakpoints): New funcs.
+       (update_breakpoints_after_exec): Delete and re-initialize
+       overlay event breakpoints after an exec.  Add FIXME comment
+       about longjmp breakpoint.
+       (print_it_typical): Ignore overlay event breakpoints.
+       (print_one_breakpoint): Ditto.
+       (mention): Ditto.
+       (bpstat_what): Do not stop for overlay event breakpoints.
+       (delete_breakpoint): Don't delete overlay event breakpoints.
+       (breakpoint_re_set_one): Delete the overlay event breakpoint.
+       (breakpoint_re_set): Re-create overlay event breakpoint.
+
+       * symfile.c (overlay_auto_command): Enable overlay breakpoints.
+       (overlay_manual_command): Disable overlay breakpoints.
+       (overlay_off_command): Disable overlay breakpoints.
+
+2002-02-06  Richard Earnshaw  <rearnsha@arm.com>
+
+       * arm-tdep.c: Include elf-bfd.h and coff/internal.h.
+       (MSYMBOL_SET_SPECIAL, MSYMBOL_IS_SPECIAL, MSYMBOL_SIZE): Move defines
+       to here from config/tm-arm.h.
+       (coff_sym_is_thumb): Make static.
+       (arm_elf_make_msymbol_special): New function.
+       (arm_coff_make_msymbol_special): New function.
+       * config/arm/tm-arm.h (MSYMBOL_SET_SPECIAL): Delete definition.
+       (MSYMBOL_IS_SPECIAL, MSYMBOL_SIZE): Likewise.
+       (coff_sym_is_thumb): Delete declaration.
+       (arm_elf_make_msymbol_special): Declare.
+       (arm_coff_make_msymbol_special): Declare.
+       (ELF_MAKE_MSYMBOL_SPECIAL): Call arm_elf_make_msymbol_special.
+       (COFF_MAKE_MSYMBOL_SPECIAL): Call arm_coff_make_msymbol_special.
+
+2002-02-06  Richard Earnshaw  <rearnsha@arm.com>
+
+       * arm-tdep.c (arm_software_single_step): ANSIfy function declaration.
+
+2002-02-06  Richard Earnshaw  <rearnsha@arm.com>
+
+       * gdbarch.sh (PRINT_FLOAT_INFO): Add rule.
+       * gdbarch.c gdbarch.h: Regenerate.
+       * arch-utils.c (default_print_float_info): New function.
+       * arch-utils.h (default_print_float_info): Prototype it.
+       * infcmd.c (float_info): Call PRINT_FLOAT_INFO.
+       * doc/gdbint.texinfo (FLOAT_INFO): Mark as deprecated.
+       (PRINT_FLOAT_INFO): Document it.
+
+       * arm-tdep.c (arm_print_float_info): Renamed from arm_float_info.
+       * config/arm/tm-arm.h (FLOAT_INFO): Delete.
+       (PRINT_FLOAT_INFO): Define.
+
+2002-02-06  Pierre Muller  <muller@ics.u-strasbg.fr>
+
+       * win32-nat.c (_initialize_check_for_gdb_ini):
+       Add typecast to sprintf argument to suppress a warning.
+
+2002-02-05  Pierre Muller  <muller@ics.u-strasbg.fr>
+
+       * win32-nat.c (last_sig): Changed type of variable to target_signal,
+       to allow easier handling of pass state.
+       (DEBUG_EXCEPTION_SIMPLE): New macro, used in handle_exception,
+       that gives exception name and address.
+       (handle_exception): Use DEBUG_EXCEPTION_SIMPLE macro
+       and set last_sig value to ourstatus->value.sig. Some missing
+       exceptions added.
+       (child_continue): Correctly report continue_status.
+       (get_child_debug_event,do_initial_child_stuff): Set last_sig to
+       TARGET_SIGNAL_0 (new default value).
+       (child_resume): consider sig argument passed to decide if
+       the exception should be passed to debuggee or not.
+
+2002-02-05  Michael Snyder  <msnyder@redhat.com>
+
+       * regcache.c (fetch_register): Call target_fetch_register
+       only if we don't call FETCH_PSEUDO_REGISTER.
+       (store_register): Call target_store_register only if we
+       don't call STORE_PSEUDO_REGISTER.
+
+2002-02-05  Elena Zannoni  <ezannoni@redhat.com>
+
+       * gdbarch.sh: Add definitions for COFF_MAKEMSYMBOL_SPECIAL and
+       ELF_MAKE_MSYMBOL_SPECIAL.
+       * gdbarch.c, gdbarch.h: Regenerate.
+       * arch-utils.c (default_make_msymbol_special): New function.
+       * arch-utils.h (default_make_msymbol_special): Export.
+       * elfread.c (elf_symtab_read): Compile use of
+       ELF_MAKE_MSYMBOL_SPECIAL unconditionally because it is now
+       multiarched.
+       * coffread.c (coff_symtab_read): Ditto, for
+       COFF_MAKE_MSYMBOL_SPECIAL.
+
+2002-02-05  Jim Blandy  <jimb@redhat.com>
+
+       * solib-svr4.c (svr4_truncate_ptr): New function.
+       (svr4_relocate_section_addresses): Do the address arithmetic with
+       the appropriate truncation for target addresses, even when
+       CORE_ADDR is larger than a target address.
+
+2002-02-05  Daniel Jacobowitz  <drow@mvista.com>
+
+       * gdbserver/linux-low.c (mywait): Cast second argument of waitpid
+       to (int *).
+
+2002-02-05  Daniel Jacobowitz  <drow@mvista.com>
+
+       * gdbserver/linux-low.c (kill_inferior): Remove commented out
+       code.
+
+2002-02-05  Daniel Jacobowitz  <drow@mvista.com>
+
+        * c-valprint.c (c_val_print): Handle TYPE_CODE_COMPLEX.
+
+2002-02-05  Daniel Jacobowitz  <drow@mvista.com>
+
+       * gdbserver/linux-low.c: Remove unused include files.
+
+2002-02-05  Daniel Jacobowitz  <drow@mvista.com>
+
+       * gdbserver/linux-low.c: Define PTRACE_ARG3_TYPE.
+       (read_inferior_memory): Use it.
+       (write_inferior_memory): Likewise.
+
+2002-02-05  Daniel Jacobowitz  <drow@mvista.com>
+
+       * gdbserver/linux-low.c (create_inferior): Call strerror instead of
+       grubbing through sys_errlist.
+
+2002-02-05  Daniel Jacobowitz  <drow@mvista.com>
+
+       * gdbserver/linux-low.c: New file, copied exactly from low-linux.c.
+
+2002-02-04  Pierre Muller  <muller@ics.u-strasbg.fr>
+       * win32-nat.c (handle_exception): Handle Ctrl-Break exception.
+
+2002-02-04  Andrew Cagney  <ac131313@redhat.com>
+
+       * cli/cli-decode.c (do_cfunc, set_cmd_cfunc): New functions.
+       (do_sfunc, set_cmd_sfunc): New functions.
+
+       * command.h (struct cmd_list_element): Add field func.
+       * cli/cli-decode.h (struct cmd_list_element): Ditto.
+       * command.h (set_cmd_sfunc, set_cmd_cfunc): Declare.
+       * cli/cli-decode.h: Ditto.
+
+       * cli/cli-decode.c (help_cmd): Test for func not cfunc/sfunc.
+       (help_all, help_cmd_list): Ditto.
+       (find_cmd, complete_on_cmdlist): Ditto.
+       * top.c (execute_command): Ditto.
+
+       * cli/cli-setshow.c (do_setshow_command): Call func instead of
+       function.sfunc.
+
+       * infcmd.c (notice_args_read): Fix function signature.
+
+       * cli/cli-cmds.c (init_cli_cmds): Use set_cmd_sfunc.
+       * cli/cli-decode.c (add_set_cmd): Ditto.
+       * utils.c (initialize_utils): Ditto.
+       * maint.c (_initialize_maint_cmds): Ditto.
+       * infrun.c (_initialize_infrun): Ditto.
+       * demangle.c (_initialize_demangler): Ditto.
+       * remote.c (add_packet_config_cmd): Ditto.
+       * mips-tdep.c (_initialize_mips_tdep): Ditto.
+       * cris-tdep.c (_initialize_cris_tdep): Ditto.
+       * proc-api.c (_initialize_proc_api): Ditto.
+       * kod.c (_initialize_kod): Ditto.
+       * valprint.c (_initialize_valprint): Ditto.
+       * top.c (init_main): Ditto.
+       * infcmd.c (_initialize_infcmd): Ditto.
+       * corefile.c (_initialize_core): Ditto.
+       * arm-tdep.c (_initialize_arm_tdep): Ditto.
+       * arch-utils.c (initialize_current_architecture): Ditto.
+       (_initialize_gdbarch_utils): Ditto.
+       * alpha-tdep.c (_initialize_alpha_tdep): Ditto.
+
+       * cli/cli-decode.c (add_cmd): Use set_cmd_cfunc.
+       * wince.c (_initialize_inftarg): Ditto.
+       * symfile.c (_initialize_symfile): Ditto.
+       * mips-tdep.c (_initialize_mips_tdep): Ditto.
+       * language.c (_initialize_language): Ditto.
+       * arc-tdep.c (_initialize_arc_tdep): Ditto.
+
+2002-02-04  Michael Snyder  <msnyder@redhat.com>
+
+       * memattr.c (_initialize_mem): Elaborate the help for 'mem' command.
+
+2002-02-04  Daniel Jacobowitz  <drow@mvista.com>
+
+       * gdbserver/Makefile.in: Add regformats directory to INCLUDE_CFLAGS.
+       Add rules for building the register data files.
+
+2002-02-04  Daniel Jacobowitz  <drow@mvista.com>
+
+       * regformats/regdat.sh: Add braces to the definition of
+       expedite_regs_${arch}.
+
+2002-02-04  Daniel Jacobowitz  <drow@mvista.com>
+
+       * regformats/regdef.h (struct reg): Add comment describing the
+       requirements for offset and size fields.
+
+2002-02-04  Andreas Schwab  <schwab@suse.de>
+
+       * config/ia64/linux.mh: Don't set NAT_CLIBS and REGEX.
+       * config/ia64/linux.mt: Don't set GDBSERVER_LIBS.
+
+2002-02-04  Richard Earnshaw  <rearnsha@arm.com>
+
+       * gdbarch.sh (copyright): Update years in generated header.
+       (SMASH_TEXT_ADDRESS): Add rule.
+       * gdbarch.h, gdbarch.c: Re-generate.
+       * coffread.c: Multi-arch uses of SMASH_TEXT_ADDRESS.
+       * dbxread.c: Likewise.
+       * dwarfread.c: Likewise.
+       * elfread.c: Likewise.
+       * somread.c: Likewise.
+
+       * arm-tdep.c (arm_smash_text_address): New function.
+       * config/arm/tm-arm.h (SMASH_TEXT_ADDRESS): Define in terms of above.
+
+2002-02-04  Pierre Muller  <muller@ics.u-strasbg.fr>
+
+       Add support for hardware watchpoints on win32 native.
+       * win32-nat.c (CONTEXT_DEBUG_DR macro): Add use of
+       CONTEXT_DEBUG_REGISTERS.
+       (dr variable): New variable. Static array containing a local copy
+       of debug registers.
+       (debug_registers_changed): New variable.  Reflects when debug registers
+       are changed and need to be written to inferior.
+       (debug_registers_used): New variable. Reflects when any debug register
+       was set, used when new threads are created.
+       (cygwin_set_dr, cygwin_set_dr7, cygwin_get_dr6): New functions used by
+       i386-nat code.
+       (thread_rec): Set dr array if id is the thread of current_event .
+       (child_continue, child_resume): Change the debug registers for all
+       threads if debug_registers_changed.
+       (child_add_thread): Change the debug registers if debug_registers_used.
+       * config/i386/cygwin.mh: Add use of i386-nat.o file.
+       Link nm.h to new nm-cygwin.h file.
+       + config/i386/nm-cygwin.h: New file. Contains the macros used for use
+       of hardware registers.
+
+2002-02-03  Andrew Cagney  <ac131313@redhat.com>
+
+       * valprint.c (print_floating): Allow non TYPE_CODE_FLT types.
+       Restore behavour broken by 2002-01-20 Andrew Cagney
+       <ac131313@redhat.com> IEEE_FLOAT removal.
+
+2002-02-03  Daniel Jacobowitz  <drow@mvista.com>
+
+       * c-valprint.c (c_val_print): Pass a proper valaddr to
+       cp_print_class_method.
+       * valops.c (search_struct_method): If there is only one method
+       and args is NULL, return that method.
+
+2002-02-03  Daniel Jacobowitz  <drow@mvista.com>
+
+       * gdbtypes.c (init_simd_type): Use TYPE_TAG_NAME instead of
+       accessing tag_name directly.
+
+2002-02-03  Daniel Jacobowitz  <drow@mvista.com>
+
+       * ax-gdb.c (find_field): Use TYPE_TAG_NAME instead
+       of accessing tag_name directly.
+
+2002-02-03  Daniel Jacobowitz  <drow@mvista.com>
+
+       PR gdb/280
+       * gdbtypes.c (replace_type): New function.
+       * gdbtypes.h (replace_type): Add prototype.
+       * stabsread.c (read_type): Use replace_type.
+
+2002-02-03  Richard Earnshaw  <rearnsha@arm.com>
+
+       * Makefile.in (memattr.o): Add missing dependencies rule.
+
+2002-02-03  Peter Schauer  <pes@regent.e-technik.tu-muenchen.de>
+
+       * breakpoint.c (break_at_finish_command): Really export.
+       (break_at_finish_at_depth_command): Ditto.
+       (tbreak_at_finish_command): Ditto.
+       * hppa-tdep.c: Include completer.h.
+       * Makefile.in (hppa-tdep.o): Add dependency on $(completer_h).
+       (COMMON_OBS): Remove duplicate ui-file.o, frame.o, doublest.o.
+
+2002-02-01  Andrew Cagney  <ac131313@redhat.com>
+
+       * utils.c (do_write): New function.
+       (error_stream): Rewrite combining the code from error_begin and
+       verror.
+       (verror): Rewrite using error_stream.
+       (error_begin): Delete function.
+
+2002-02-01  Andrew Cagney  <ac131313@redhat.com>
+
+       * utils.c (error_begin): Make static.
+       * defs.h (error_begin): Delete declaration.
+
+       * linespec.c (cplusplus_error): Replace cplusplus_hint.
+       (decode_line_1): Use cplusplus_error instead of error_begin,
+       cplusplus_hint and return_to_top_level.
+       * coffread.c (coff_symfile_read): Use error instead of error_begin
+       and return_to_top_level.
+       * infrun.c (default_skip_permanent_breakpoint): Ditto.
+
+2002-02-01  Andrew Cagney  <ac131313@redhat.com>
+
+       * language.h (type_error, range_error): Make string parameter
+       constant.
+       * language.c (warning_pre_print): Delete extern declaration.
+       * dwarfread.c (warning_pre_print): Ditto.
+       * language.c (type_error, range_error): Rewrite to use verror and
+       vwarning instead of warning_begin.
+
+2002-02-01  Michael Snyder  <msnyder@redhat.com>
+
+       * breakpoint.c (breakpoint_re_set): Delete ancient #if 0 code.
+       (set_ignore_count): Move misplaced comment back where it belongs.
+
+2002-02-01  Andrew Cagney  <ac131313@redhat.com>
+
+       * command.h (NO_FUNCTION): Delete macro.
+       * cli/cli-decode.h (NO_FUNCTION): Ditto.
+       * top.c (execute_command): Replace NO_FUNCTION with NULL.
+       * tracepoint.c (_initialize_tracepoint): Ditto.
+       * cli/cli-decode.c (add_set_cmd): Ditto.
+       * cli/cli-cmds.c (init_cli_cmds): Ditto.
+
+2002-02-01  Daniel Jacobowitz  <drow@mvista.com>
+
+       * gnu-v3-abi.c (gnuv3_virtual_fn_field): Update comments.
+       Update ``this'' pointer when calling virtual functions.
+
+2002-02-01  Michael Snyder  <msnyder@redhat.com>
+
+       * breakpoint.c (create_temp_exception_breakpoint): Delete.
+       * hppa-tdep.c: Deprecate xbreak, txbreak and bx commands.
+
+2002-02-01  Daniel Jacobowitz  <drow@mvista.com>
+
+       * regformats/reg-arm.dat: New file.
+       * regformats/reg-i386.dat: New file.
+       * regformats/reg-ia64.dat: New file.
+       * regformats/reg-m68k.dat: New file.
+       * regformats/reg-mips.dat: New file.
+       * regformats/reg-ppc.dat: New file.
+       * regformats/reg-sh.dat: New file.
+       * regformats/regdef.h: New file.
+       * regformats/regdat.sh: New file.
+
+2002-02-01  Richard Earnshaw  <reanrsha@arm.com>
+
+       * arm-tdep.c (arm_frameless_function_invocation): Add some comments.
+       (arm_frame_args_address, arm_frame_locals_address): New functions.
+       (arm_frame_num_args): New function.
+       * config/tm-arm.h (FRAME_ARGS_ADDRESS): Call arm_frame_args_address.
+       (FRAME_LOCALS_ADDRESS): Call arm_frame_locals_address.
+       (FRMA_NUM_ARGS): Call arm_frame_num_args.
+
+2002-01-31  Michael Snyder  <msnyder@redhat.com>
+
+       * breakpoint.c (break_at_finish_command): Export.
+       (break_at_finish_at_depth_command): Export.
+       (tbreak_at_finish_command): Export.
+       (_initialize_breakpoint): Delete "xbreak" and "tbreak" commands.
+       * hppa-tdep.c (_initialize_hppa_tdep): Add "xbreak" and
+       "tbreak" commands, which are HPPA specific.
+
+       * printcmd.c (disassemble_command): Remove an ancient
+       artifact of an old merge.
+
+       * symfile.h (enum overlay_debugging_state):
+       Define enum constant values for overlay mode.
+       * symfile.c (overlay_debugging): Use enums instead of literals.
+       (overlay_is_mapped, overlay_auto_command,
+       overlay_manual_command): Ditto.
+
+       * breakpoint.c (insert_breakpoints, remove_breakpoint,
+       breakpoint_here_p, breakpoint_inserted_here_p,
+       breakpoint_thread_match, bpstat_stop_status,
+       describe_other_breakpoints, check_duplicates, clear_command):
+       Coding standard fixes.
+
+       * target.c (target_xfer_memory): Add spaces, coding standard.
+       (do_xfer_memory): Add missing line to trust-readonly
+       code: check bfd SEC_READONLY flag for section.
+
+2002-01-31  Andrew Cagney  <ac131313@redhat.com>
+
+       * PROBLEMS: Fix typo, 5.1->5.1.1.
+
+2002-01-30  Daniel Jacobowitz  <drow@mvista.com>
+
+       * symtab.c (find_pc_sect_psymtab): Do not search psymtabs for
+       data symbols, since we search based on textlow and texthigh.
+       (find_pc_sect_symtab): Likewise.
+
+2002-01-30  Andrew Cagney  <ac131313@redhat.com>
+
+       * defs.h (vwarning): Declare.
+       * utils.c (vwarning): New function.
+       (warning): Call vwarning.
+       (warning_begin): Delete function.
+
+       * rs6000-nat.c (vmap_ldinfo): Use the function warning to print
+       the warning message.
+       * d10v-tdep.c (d10v_address_to_pointer) [0]: Delete call to
+       warning_begin.
+
+2002-01-30  Michael Snyder  <msnyder@redhat.com>
+
+       * NEWS: Mention "set trust-readonly-sections" command.
+       Mention generate-core-file command.
+
+2002-01-15  Michael Snyder  <msnyder@redhat.com>
+
+       * target.c: New command, "set trust-readonly-sections on".
+       (do_xfer_memory): Honor the suggestion to trust readonly sections
+       by reading them from the object file instead of from the target.
+       (initialize_targets): Register command "set trust-readonly-sections".
+
+2002-01-29  Andrew Cagney  <ac131313@redhat.com>
+
+       * parse.c (target_map_name_to_register): Simplify, search regs and
+       pseudo-regs using a single loop.
+
+2002-01-30  Andrew Cagney  <ac131313@redhat.com>
+
+       * PROBLEMS: Note that the i386 fix was missing from 5.1.1.
+
+2002-01-15  Rodney Brown  <rbrown64@csc.com.au>
+
+       * config/i386/tm-i386v4.h: Define HAVE_I387_REGS.
+       * config/i386/i386v42mp.mh: Add i387-nat.o .
+       * i386v4-nat.c: Include i387-nat.h.
+       (supply_fpregset): Use i387_supply_fsave.
+       (fill_fpregset): Use i387_fill_fsave.
+
+2002-01-30  Richard Earnshaw  <rearnsha@arm.com>
+
+       * arm-tdep.c (arm_call_dummy_words): Define.
+       * arm-linux-tdep.c (arm_linux_call_dummy_words): Define.
+       * config/arm/tm-arm.h (CALL_DUMMY_P): Define.
+       (CALL_DUMMY_WORDS): Define.
+       (arm_call_dummy_words): Declare.
+       * config/arm/tm-linux.h (CALL_DUMMY_WORDS): Define.
+       (arm_linux_call_dummy_words): Declare.
+
+2002-01-30  Andreas Schwab  <schwab@suse.de>
+
+       * m68klinux-nat.c: Fix last change to use regcache_collect
+       instead of referencing registers[] directly.
+
+2002-01-29  Andrew Cagney  <ac131313@redhat.com>
+
+       * parse.c (target_map_name_to_register): Delete code wrapped in
+       #ifdef REGISTER_NAME_ALIAS_HOOK.
+
+2002-01-28  Michael Snyder  <msnyder@redhat.com>
+
+       * regcache.c (legacy_read_register_gen): Need to be able to
+       read pseudo-register as well as real register.
+       (legacy_write_register_gen): Ditto.
+
+2002-01-28  Andrew Cagney  <ac131313@redhat.com>
+
+       * config/mips/tm-wince.h (TARGET_BYTE_ORDER): Delete.
+       * config/sparc/tm-sparc.h (TARGET_BYTE_ORDER): Delete.
+       * config/ns32k/tm-umax.h (TARGET_BYTE_ORDER): Delete.
+       * config/ia64/tm-ia64.h (TARGET_BYTE_ORDER): Delete.
+       * config/m32r/tm-m32r.h (TARGET_BYTE_ORDER): Delete.
+       * config/m68k/tm-m68k.h (TARGET_BYTE_ORDER): Delete.
+       * config/m88k/tm-m88k.h (TARGET_BYTE_ORDER): Delete.
+       * config/mn10200/tm-mn10200.h (TARGET_BYTE_ORDER): Delete.
+       * config/pa/tm-hppa.h (TARGET_BYTE_ORDER): Delete.
+       * config/sh/tm-wince.h (TARGET_BYTE_ORDER): Delete.
+       * config/v850/tm-v850.h (TARGET_BYTE_ORDER): Delete.
+       * config/vax/tm-vax.h (TARGET_BYTE_ORDER): Delete.
+       * config/z8k/tm-z8k.h (TARGET_BYTE_ORDER): Delete.
+       * config/i960/tm-i960.h (TARGET_BYTE_ORDER): Delete.
+       * config/i386/tm-i386.h (TARGET_BYTE_ORDER): Delete.
+       * config/h8500/tm-h8500.h (TARGET_BYTE_ORDER): Delete.
+       * config/h8300/tm-h8300.h (TARGET_BYTE_ORDER): Delete.
+       * config/fr30/tm-fr30.h (TARGET_BYTE_ORDER): Delete.
+       * config/d30v/tm-d30v.h (TARGET_BYTE_ORDER): Delete.
+       * config/alpha/tm-alpha.h (TARGET_BYTE_ORDER): Delete.
+
+2002-01-28  Andrew Cagney  <ac131313@redhat.com>
+
+       * arch-utils.c (TARGET_BYTE_ORDER_DEFAULT): Delete macro.
+       (target_byte_order): Initialize to BFD_ENDIAN_BIG.
+       (initialize_current_architecture): Update target_byte_order using
+       information from BFD.
+       * config/mcore/tm-mcore.h (TARGET_BYTE_ORDER_DEFAULT):
+       * config/arm/tm-arm.h (TARGET_BYTE_ORDER_DEFAULT): Delete.
+
+2002-01-28  Andrew Cagney  <ac131313@redhat.com>
+
+       * config/vax/tm-vax.h (INVALID_FLOAT): Move macro from here...
+       * vax-tdep.c (INVALID_FLOAT): To here.  Document why it is broken.
+
+       * rs6000-tdep.c (rs6000_do_registers_info): Delete code wrapped in
+       #ifdef INVALID_FLOAT.
+       * infcmd.c (do_registers_info): Ditto.
+       * values.c (unpack_double): Ditto.  Add comment.
+
+       * config/ns32k/tm-umax.h (INVALID_FLOAT): Delete macro that was
+       already commented out.
+
+2002-01-26  Andreas Schwab  <schwab@suse.de>
+
+       * config/m68k/nm-linux.h (FETCH_INFERIOR_REGISTERS): Define.
+       * m68klinux-nat.c: Update ptrace interface for fetching/storing
+       registers and add support for PTRACE_GETREGS.
+
+2002-01-24  Andrew Cagney  <ac131313@redhat.com>
+
+       GDB 5.1.1 released from 5.1 branch.
+       * NEWS: Add 5.1.1 news.
+       * README: Sync with 5.1 branch.
+
+2002-01-23  Fred Fish  <fnf@redhat.com>
+
+       * mdebugread.c (parse_partial_symbols): Only copy stabstring1 to
+       stabstring on initial malloc.  Reallocing will copy it for us,
+       if necessary.
+
+2002-01-23  Elena Zannoni  <ezannoni@redhat.com>
+
+        * Makefile.in (hpread_h): Delete.
+        (HFILES_NO_SRCDIR): Remove hpread.h.
+        (ALLDEPFILES): Remove hp-psymtab-read.c and hp-symtab-read.c.
+        (hpread.o): Update dependencies.
+        (hp-psymtab-read.o, hp-symtab-read.o): Remove.
+
+        * hp-psymtab-read.c: Remove file.
+        * hp-symtab-read.c: Remove file.
+        * hpread.h: Remove file.
+
+        * hpread.c: Merge all contents of hp-psymtab-read.c,
+        hp-symtab-read.c and hpread.h into this file, as it was prior to
+        January 1999.
+
+        * config/pa/hpux11w.mh, config/pa/hpux11.mh,
+        config/pa/hpux1020.mh, config/pa/hppaosf.mh,
+        config/pa/hppahpux.mh, config/pa/hppabsd.mh (NATDEPFILES):
+        Remove hp-psymtab-read.o and hp-symtab-read.o, add hpread.o.
+
+2002-01-23  Elena Zannoni  <ezannoni@redhat.com>
+
+       * ppc-linux-nat.c (ppc_register_u_addr, supply_gregset,
+       fill_gregset): Call gdbarch_tdep() just once, assign result to
+       variable and use that, instead of calling the function several
+       times.
+
+2002-01-24  Alexandre Oliva  <aoliva@redhat.com>
+
+       * configure.host: Accept sparcv9 as alias for sparc64.
+       * configure.tgt: Likewise.
+
+2002-01-22  Kevin Buettner  <kevinb@redhat.com>
+
+       * solib-aix5.c (build_so_list_from_mapfile)
+       (aix5_relocate_main_executable): Fix xcalloc() calls so order of
+       arguments is not reversed.
+       * solib-sunos.c (sunos_relocate_main_executable): Likewise.
+       * solib-svr4.c (svr4_relocate_main_executable): Likewise.
+
+2002-01-22  Elena Zannoni  <ezannoni@redhat.com>
+
+       * sh-tdep.c (sh_pseudo_register_read): New function. Renamed and
+       modified version of obsolete sh_fetch_pseudo_register.
+       (sh_fetch_pseudo_register): Rename to sh_pseudo_register_read.
+       (sh4_register_read): New function.
+       (sh_pseudo_register_write): New function. Renamed and modified
+       version of obsolete sh_store_pseudo_register.
+       (sh_store_pseudo_register): Rename to sh_pseudo_register_write.
+       (sh4_register_write): New function.
+       (sh_gdbarch_init): Remove setting of gdbarch function
+       fetch_pseudo_register and store_pseudo_register. Remove setting of
+       register_convert_to_raw, register_convert_to_virtual,
+       register_convertible.
+       (sh_sh4_register_convertible): Delete. No longer needed. All is
+       taken care by architecture specific functions
+       register_read/register_write.
+       (sh_sh4_register_convert_to_virtual): Make static.
+       (sh_sh4_register_convert_to_raw): Ditto.
+
+2002-01-22  Andrew Cagney  <ac131313@redhat.com>
+
+       * doublest.c (floatformat_is_negative): Assert FMT is non NULL.
+       (floatformat_is_nan, floatformat_mantissa): Ditto.
+
+       * gdbtypes.c (_initialize_gdbtypes): Initialize TYPE_FLOATFORMAT
+       for builtin_type_ieee_single_little, builtin_type_ieee_double_big,
+       builtin_type_ieee_double_little,
+       builtin_type_ieee_double_littlebyte_bigword,
+       builtin_type_m68881_ext, builtin_type_i960_ext,
+       builtin_type_m88110_ext, builtin_type_m88110_harris_ext,
+       builtin_type_arm_ext_big, builtin_type_arm_ext_littlebyte_bigword,
+       builtin_type_ia64_spill_big, builtin_type_ia64_spill_little and
+       builtin_type_ia64_quad_big, builtin_type_ia64_quad_little.
+
+2002-01-22  Corinna Vinschen  <vinschen@redhat.com>
+
+       * xstormy16-tdep.c (xstormy16_scan_prologue): Add frameless
+       parameter.  Set frameless flag if it exists and depended of
+       whether the scanned function is frameless or not.
+       (xstormy16_skip_prologue): If function is frameless, return
+       result of xstormy16_scan_prologue().
+       (xstormy16_frame_init_saved_regs): Adjust xstormy16_scan_prologue()
+       call.
+
+2002-01-21  Elena Zannoni  <ezannoni@redhat.com>
+
+       * sh-tdep.c (sh_fp_frame_init_saved_regs, sh_push_arguments,
+       sh_generic_show_regs, sh3_show_regs, sh3e_show_regs,
+       sh3_dsp_show_regs, sh4_show_regs, sh_dsp_show_regs,
+       sh_sh4_register_byte, sh_sh4_register_raw_size,
+       sh_sh3e_register_virtual_type, sh_sh4_register_virtual_type,
+       sh_sh4_register_convertible, sh_sh4_register_convert_to_virtual,
+       sh_sh4_register_convert_to_raw, sh_fetch_pseudo_register,
+       sh_store_pseudo_register, sh_do_pseudo_register): Call
+       gdbarch_tdep() just once, assign result to variable and use that,
+       instead of calling the function several times.
+
+2002-01-20  Mark Kettenis  <kettenis@gnu.org>
+
+       * go32-nat.c (fetch_register): Use FP_REGNUM_P and FPC_REGNUM_P
+       macros instead of LAST_FPU_CTRL_REGNUM.
+       (store_register): Likewise.
+
+2002-01-21  Jim Blandy  <jimb@redhat.com>
+
+       * infcmd.c (run_command): Check that the `exec' target layer's BFD
+       is up-to-date before running the program, not just when a program
+       exits.
+
+2002-01-21  Fred Fish  <fnf@redhat.com>
+
+       * arm-tdep.c (thumb_skip_prologue): Quit scanning prologue
+       when we have found all instructions we are looking for.
+
+2002-01-21  Richard Earnshaw  <rearnsha@arm.com>
+
+       * arm-tdep.c (arm_register_name): New function.
+       (arm_registers_names): Make static.
+       * config/arm/tm-arm.h (arm_register_names): Delete declaration.
+       (arm_register_name): Declare.
+       (REGISTER_NAME): Use it.
+
+2002-01-21  Richard Earnshaw  <rearnsha@arm.com>
+           Kevin Buettner  <kevinb@redhat.com>
+
+       Convert arm targets to new FRAME interface.
+       * arm-tdep.c (struct frame_extra_info): Remove fsr.
+       (arm_frame_find_save_regs): Delete.
+       (arm_frame_init_saved_regs): New.
+       (arm_init_extra_frame_info): Alloacte saved_regs as required.
+       Allocate extra_info as required.  Convert all uses of fsr.regs
+       to use saved_regs, similarly all uses of EXTRA_FRAME_INFO fields
+       to use extra_info.
+       (thumb_scan_prologue, arm_scan_prologue, arm_find_callers_reg)
+       (arm_frame_chain, arm_frame_saved_pc, arm_pop_frame): Likewise.
+       (check_prologue_cache, save_prologue_cache): Likewise.
+       (_initialize_arm_tdep): Ensure prologue_cache is correctly set up.
+       * config/arm/tm-arm.h (EXTRA_FRAME_INFO): Delete.
+       (FRAME_FIND_SAVED_REGS): Delete.
+       (arm_frame_find_saved_regs): Delete prototype.
+       (arm_frame_init_saved_regs): New prototype.
+       (FRAME_INIT_SAVED_REGS): Define.
+
+2002-01-20  Andrew Cagney  <ac131313@redhat.com>
+
+       * config/arc/tm-arc.h (IEEE_FLOAT): Delete.
+
+2002-01-20  Andrew Cagney  <ac131313@redhat.com>
+
+       From Jeff Law <law@redhat.com>:
+       * infttrace.c: Include <sys/pstat.h>.
+       (child_pid_to_exec_file): Revamp.  Use pstat call to get the
+       exec file if the ttrace equivalent fails.
+
+2002-01-20  Andrew Cagney  <ac131313@redhat.com>
+
+       * rdi-share/devsw.c (openLogFile): Delete unused ``struct tm lt''.
+       (closeLogFile): Ditto.
+
+2002-01-20  Michael Chastain  <mec@shout.net>
+
+       * top.c (print_gdb_version): Bump copyright year to 2002.
+
+2002-01-20  Andrew Cagney  <ac131313@redhat.com>
+
+       * MAINTAINERS (Blanket Write Privs): Add Kevin Buettner, Elena
+       Zannoni and Eli Zaretskii.
+
+2002-01-20  Daniel Jacobowitz  <drow@mvista.com>
+
+       * buildsym.c: Update copyright years.
+       * c-typeprint.c: Likewise.
+       * dwarf2read.c: Likewise.
+       * f-typeprint.c: Likewise.
+       * gdbtypes.c: Likewise.
+       * gdbtypes.h: Likewise.
+       * hp-symtab-read.c: Likewise.
+       * hpread.c: Likewise.
+       * mdebugread.c: Likewise.
+       * p-typeprint.c: Likewise.
+
+2002-01-20  Andrew Cagney  <ac131313@redhat.com>
+
+       * remote-sim.c (gdbsim_open): Simplify code testing the macro
+       TARGET_BYTE_ORDER_SELECTABLE_P.  Assume the target is always
+       byte-order selectable.
+       * sparc-tdep.c (sparc_target_architecture_hook): Ditto.
+       * arch-utils.c: Ditto.
+       (set_endian): Ditto.
+       (set_endian_from_file): Ditto.
+       * gdbserver/low-sim.c (create_inferior): Ditto.
+       * gdbarch.sh: Ditto.
+       * gdbarch.h: Re-generate.
+       * config/powerpc/tm-ppc-eabi.h (TARGET_BYTE_ORDER_SELECTABLE_P):
+       * config/sparc/tm-sparclite.h (TARGET_BYTE_ORDER_SELECTABLE):
+       * config/sparc/tm-sparclet.h (TARGET_BYTE_ORDER_SELECTABLE):
+       * config/mcore/tm-mcore.h (TARGET_BYTE_ORDER_SELECTABLE_P):
+       * config/arm/tm-wince.h (TARGET_BYTE_ORDER_SELECTABLE_P):
+       * config/arm/tm-linux.h (TARGET_BYTE_ORDER_SELECTABLE_P):
+       * config/arc/tm-arc.h (TARGET_BYTE_ORDER_SELECTABLE):
+       * config/arm/tm-arm.h (TARGET_BYTE_ORDER_SELECTABLE_P): Delete
+       macro definition.
+       * config/mips/tm-wince.h: Remove #undef of macro
+       TARGET_BYTE_ORDER_SELECTABLE.
+       * config/sh/tm-wince.h: Ditto.
+
+2002-01-20  Daniel Jacobowitz  <drow@mvista.com>
+
+       * gdbtypes.h (struct cplus_struct_type): Add is_artificial to
+       member function fields.  Add accessor macro
+       TYPE_FN_FIELD_ARTIFICIAL.
+       * dwarf2read.c (dwarf2_add_member_fn): Check for artificial methods.
+       * c-typeprint.c (c_type_print_base): Skip artificial member
+       functions.
+
+2002-01-20  Daniel Jacobowitz  <drow@mvista.com>
+
+       * f-typeprint.c: Delete unused function f_type_print_args.
+       * p-typeprint.c: Delete unused function pascal_type_print_args.
+
+2002-01-20  Daniel Jacobowitz  <drow@mvista.com>
+
+       * gdbtypes.h (struct type): Fix whitespace.  Remove obsolete
+       comment.  Add ``artificial'' to ``union field_location''.
+
+       * dwarf2read.c: Remove ad-hoc TYPE_FIELD_ARTIFICIAL.
+
+       * buildsym.c (finish_block): Initialize TYPE_FIELD_ARTIFICIAL to 0.
+       * mdebugread.c (parse_symbol): Likewise.
+       * stabsread.c (define_symbol): Likewise.
+       * hp-symtab-read.c (hpread_function_type): Likewise, instead of
+       initializing TYPE_FIELD_BITPOS to n (obsolete).
+       (hpread_doc_function_type): Likewise.
+       * hpread.c (hpread_function_type): Likewise.
+
+2002-01-20  Andrew Cagney  <ac131313@redhat.com>
+
+       * configure.in (host_makefile_frag): Only require a host makefile
+       fragment when a native build.
+       * configure: Re-generate.
+
+2002-01-20  Andrew Cagney  <ac131313@redhat.com>
+
+       * doublest.h (floatformat_from_type): Declare.
+       * doublest.c (floatformat_from_type): New function.
+       (convert_typed_floating): Use.
+
+       * valprint.c (print_floating): Replace checks for IEEE_FLOAT with
+       call to function floatformat_from_type.
+
+       * gdbarch.sh (IEEE_FLOAT): Delete.
+       * gdbarch.h, gdbarch.c: Re-generate.
+       * config/i960/tm-i960.h (IEEE_FLOAT): Delete macro.
+       * config/i386/tm-i386.h (IEEE_FLOAT): Ditto.
+       * config/z8k/tm-z8k.h (IEEE_FLOAT): Ditto.
+       * config/sparc/tm-sparc.h (IEEE_FLOAT): Ditto.
+       * config/pa/tm-hppa.h (IEEE_FLOAT): Ditto.
+       * config/m88k/tm-m88k.h (IEEE_FLOAT): Ditto.
+       * config/m68k/tm-m68k.h (IEEE_FLOAT): Ditto.
+       * config/h8500/tm-h8500.h (IEEE_FLOAT): Ditto.
+       * config/h8300/tm-h8300.h (IEEE_FLOAT): Ditto.
+       * config/fr30/tm-fr30.h (IEEE_FLOAT): Ditto.
+       * config/arm/tm-arm.h (IEEE_FLOAT): Ditto.
+       * config/alpha/tm-alpha.h (IEEE_FLOAT): Ditto.
+
+       * s390-tdep.c (s390_gdbarch_init): Do not set ieee_float.
+       * x86-64-tdep.c (i386_gdbarch_init): Ditto.
+       * sparc-tdep.c (sparc_gdbarch_init): Ditto.
+       * sh-tdep.c (sh_gdbarch_init): Ditto.
+       * mips-tdep.c (mips_gdbarch_init): Ditto.
+       * m68hc11-tdep.c (m68hc11_gdbarch_init): Ditto.
+       * cris-tdep.c (cris_gdbarch_init): Ditto.
+
+2002-01-20  Jiri Smid  <smid@suse.cz>
+
+       * configure.host, configure.tgt: Support x86-64.
+       * NEWS: Note new target x86-64.
+
+       * config/i386/x86-64linux.mh (NATDEPFILES): x86-64-nat.o removed.
+       * x86-64-linux-nat.c (x86_64_register_u_addr): New function.
+       * config/i386/nm-x86-64.h (ATTACH_LWP): Removed.
+       * Makefile.in (x86-64-tdep.o, x86-64-linux-tdep.o,
+       x86-64-linux-nat.o): Fix dependencies.
+
+2002-01-19  Andrew Cagney  <ac131313@redhat.com>
+
+       * utils.c: Remove #ifndef MALLOC_INCOMPATIBLE.
+       * config/sparc/xm-sun4os4.h (PTRACE_ARG3_TYPE): Move macro ....
+       * config/sparc/nm-sun4os4.h (PTRACE_ARG3_TYPE): ... to here.
+       * config/sparc/xm-sun4os4.h: Delete file.
+       * config/sparc/sun4os4.mh (XM_FILE): Delete makefile variable.
+
+2002-01-19  Andrew Cagney  <ac131313@redhat.com>
+
+       * config/sparc/sparclynx.mh (XM_FILE): Delete.
+       * config/rs6000/rs6000lynx.mh (XM_FILE): Delete.
+       * config/m68k/m68klynx.mh (XM_FILE): Delete.
+       * config/i386/i386lynx.mh (XM_FILE): Delete.
+       * config/rs6000/xm-rs6000ly.h: Delete file.
+       * config/sparc/xm-sparclynx.h: Delete file.
+       * config/m68k/xm-m68klynx.h: Delete file.
+       * config/i386/xm-i386lynx.h: Delete file.
+       * config/xm-lynx.h: Delete file.
+       * config/djgpp/fnchange.lst: Update.
+
+2002-01-19  Jason Thorpe  <thorpej@wasabisystems.com>
+
+       * alpha-tdep.c (alpha_register_byte): New function.
+       (alpha_register_raw_size): Ditto.
+       (alpha_register_virtual_size): Ditto.
+       (alpha_skip_prologue_internal): Renamed from
+       alpha_skip_prologue.
+       (alpha_skip_prologue): New version that calls
+       alpha_skip_prologue_internal.
+       (alpha_in_lenient_prologue): Use alpha_skip_prologue_internal.
+       * config/alpha/tm-alpha.h (SKIP_PROLOGUE): Remove
+       second argument from alpha_skip_prologue.
+       (REGISTER_BYTE): Use alpha_register_byte.
+       (REGISTER_RAW_SIZE): Use alpha_register_raw_size.
+       (REGISTER_VIRTUAL_SIZE): Use alpha_register_virtual_size.
+       (FRAMELESS_FUNCTION_INVOCATION): Use
+       generic_frameless_function_invocation_not.
+       (FRAME_NUM_ARGS): Use frame_num_args_unknown.
+       (COERCE_FLOAT_TO_DOUBLE): Use standard_coerce_float_to_double.
+
+2002-01-19  Andrew Cagney  <ac131313@redhat.com>
+
+       * config/mips/xm-news-mips.h: Delete file.
+       * config/mips/news-mips.mh (XM_FILE): Delete makefile variable.
+
+       * config/m88k/xm-m88k.h: Delete file.
+       * config/m88k/xm-dgux.h: Do not include xm-m88k.h.
+       * config/m88k/xm-delta88v4.h: Ditto.
+       * config/m88k/xm-delta88.h: Ditto.
+
+       * config/alpha/xm-fbsd.h: Delete file.
+       * config/alpha/fbsd.mh (XM_FILE): Delete makefile variable.
+
+       * config/sparc/xm-sparc.h: Delete file.
+       * Makefile.in (xm-sun4os4.h): Delete dependency.
+       * config/sparc/xm-sun4sol2.h: Do not include xm-sparc.h.
+       * config/sparc/xm-sun4os4.h: Ditto.
+       * config/sparc/xm-linux.h: Ditto.
+
+       * config/i386/xm-windows.h: Delete file.
+
+2002-01-19  Andrew Cagney  <ac131313@redhat.com>
+
+       * utils.c: Include <sys/param.h> for MAXPATHLEN.
+       (gdb_realpath): Use MAXPATHLEN when PATH_MAX is not defined.
+
+2002-01-19  Jason Thorpe  <thorpej@wasabisystems.com>
+
+       * alpha-tdep.c (alpha_call_dummy_words): New.
+       * config/alpha/tm-alpha.h (CALL_DUMMY): Remove.
+       (CALL_DUMMY_P): Define.
+       (CALL_DUMMY_WORDS): Define.
+       (SIZEOF_CALL_DUMMY_WORDS): Define.
+
+2002-01-19  Per Bothner  <per@bothner.com>
+
+       * gnu-v3-abi.c (gnuv3_rtti_type):  Guard that vtable_symbol_name
+       isn't NULL, which can happen with some gcj-3.x-produced code.
+
+2002-01-19  Jason Thorpe  <thorpej@wasabisystems.com>
+
+       * alpha-tdep.c (alpha_register_virtual_type): New function.
+       (alpha_init_frame_pc_first): Ditto.
+       (alpha_fix_call_dummy): Ditto.
+       (alpha_store_struct_return): Ditto.
+       (alpha_extract_struct_value_address): Ditto.
+       * config/alpha/tm-alpha.h (REGISTER_VIRTUAL_TYPE): Use
+       alpha_register_virtual_type.
+       (STORE_STRUCT_RETURN): Use alpha_store_struct_return.
+       (EXTRACT_STRUCT_VALUE_ADDRESS): Use
+       alpha_extract_struct_value_address.
+       (FIX_CALL_DUMMY): Use alpha_fix_call_dummy.
+       (INIT_FRAME_PC): Use init_frame_pc_noop.
+       (INIT_FRAME_PC_FIRST): Use alpha_init_frame_pc_first.
+
+2002-01-19  Mark Kettenis  <kettenis@gnu.org>
+
+       * i386gnu-nat.c: Include "i386-tdep.h".
+       (fetch_fpregs): Simplify code dealing with uninitialized floating
+       point states such that it doesn't require FP7_REGNUM.
+
+2002-01-18  Jason Thorpe  <thorpej@wasabisystems.com>
+
+       * alpha-tdep.c (frame_extra_info): New.
+       (alpha_find_saved_regs): Make static.  Use
+       frame->extra_info.
+       (alpha_frame_init_saved_regs): New function.
+       (alpha_frame_saved_pc): Use frame->extra_info.
+       (temp_saved_regs): Don't declare as struct frame_saved_regs.
+       (heuristic_proc_desc): Adjust for temp_saved_regs changes.
+       (init_extra_frame_info): Rename to...
+       (alpha_init_extra_frame_info): ...this.  Use frame->extra_info.
+       (alpha_print_extra_frame_info): New function.
+       (alpha_frame_locals_address): Ditto.
+       (alpha_frame_args_address): Ditto.
+       (alpha_pop_frame): Use frame->extra_info.
+       * config/alpha/tm-alpha.h (FRAME_ARGS_ADDRESS): Use
+       alpha_frame_args_address.
+       (FRAME_LOCALS_ADDRESS): Use alpha_frame_locals_address.
+       (alpha_find_saved_regs): Remove prototype.
+       (FRAME_INIT_SAVED_REGS): Use alpha_frame_init_saved_regs.
+       (EXTRA_FRAME_INFO): Remove.
+       (INIT_EXTRA_FRAME_INFO): Use alpha_init_extra_frame_info.
+       (PRINT_EXTRA_FRAME_INFO): Use alpha_print_extra_frame_info.
+
+2002-01-18  Jason Thorpe  <thorpej@wasabisystems.com>
+
+       * alpha-tdep.c (alpha_osf_in_sigtramp): New function.
+       (alpha_cannot_fetch_register): Ditto.
+       (alpha_cannot_store_register): Ditto.
+       (alpha_register_convertible): Ditto.
+       (alpha_use_struct_convention): Ditto.
+       * config/alpha/tm-alpha.h: Update copyright years.
+       (IN_SIGTRAMP): Use alpha_osf_in_sigtramp.
+       (INNER_THAN): Use core_addr_lessthan.
+       (CANNOT_FETCH_REGISTER): Use alpha_cannot_fetch_register.
+       (CANNOT_STORE_REGISTER): Use alpha_cannot_store_register.
+       (REGISTER_CONVERTIBLE): Use alpha_register_convertible.
+       (USE_STRUCT_CONVENTION): Use alpha_use_struct_convention.
+       (FRAME_CHAIN): Remove unnecessary cast.
+
+2002-01-18  Andrew Cagney  <ac131313@redhat.com>
+
+       * NEWS: Document that testsuite/gdb.hp/gdb.threads-hp/ is
+       obsolete.
+
+2002-01-18  Andrew Cagney  <ac131313@redhat.com>
+
+       * infptrace.c: Remove ATTRIBUTE_UNUSED.  Update copyright.
+       * monitor.c, remote-array.c, remote-bug.c: Ditto.
+       * remote-e7000.c, remote-es.c, remote-mips.c: Ditto.
+       * remote-nindy.c, remote-os9k.c, remote-rdi.c: Ditto.
+       * remote-rdp.c, remote-sds.c, remote-sim.c: Ditto.
+       * remote-st.c, remote-vx.c, remote.c, win32-nat.c: Ditto.
+       * x86-64-linux-nat.c: Ditto.
+
+2002-01-18  Jason Thorpe  <thorpej@wasabisystems.com>
+
+       * alpha-tdep.c (alpha_register_name): New function.
+       * config/alpha/tm-alpha.h (REGISTER_NAMES): Remove.
+       (REGISTER_NAME): Define.
+
+2002-01-18  Jason Thorpe  <thorpej@wasabisystems.com>
+
+       * config/nm-nbsd.h (KERNEL_U_ADDR): Remove.
+
+2002-01-18  Jason Thorpe  <thorpej@wasabisystems.com>
+
+       * alpha-tdep.c: Update copyright years.
+       (alpha_next_pc): New function.
+       (alpha_software_single_step): Ditto.
+       * config/alpha/tm-alpha.h: Add prototype for
+       alpha_software_single_step.
+
+2002-01-18  Jason Thorpe  <thorpej@wasabisystems.com>
+
+       * alphabsd-nat.c: Update copyright years.
+       (fill_gregset): Use regcache_collect.
+       (fill_fpregset): Likewise.
+       (fetch_inferior_registers): Only fetch integer registers
+       if requested to do so.
+       (store_inferior_registers): Only store integer registers
+       if requested to do so.
+
+2002-01-17  Andrew Cagney  <ac131313@redhat.com>
+
+       * config/alpha/alpha-osf3.mh (XDEPFILES): Delete.
+       * config/alpha/alpha-osf2.mh (XDEPFILES): Delete.
+       * config/alpha/alpha-osf1.mh (XDEPFILES): Delete.
+       * config/alpha/alpha-linux.mh (XDEPFILES): Delete.
+       * config/alpha/fbsd.mh (XDEPFILES): Delete.
+       * config/arm/linux.mh (XDEPFILES): Delete.
+       * config/arm/nbsd.mh (XDEPFILES): Delete.
+       * config/i386/i386dgux.mh (XDEPFILES): Delete.
+       * config/i386/i386sol2.mh (XDEPFILES): Delete.
+       * config/i386/i386m3.mh (XDEPFILES): Delete.
+       (NATDEPFILES): Move i387-tdep.o and core-aout.o to here.
+       * config/i386/i386gnu.mh (XDEPFILES): Delete.
+       * config/i386/fbsd.mh (XDEPFILES): Delete.
+       * config/i386/i386bsd.mh (XDEPFILES): Delete.
+       * config/i386/i386sco5.mh (XDEPFILES): Delete.
+       * config/i386/i386v4.mh (XDEPFILES): Delete.
+       * config/i386/i386v42mp.mh (XDEPFILES): Delete.
+       * config/i386/i386sco4.mh (XDEPFILES): Delete.
+       * config/i386/i386aix.mh (XDEPFILES): Delete.
+       * config/i386/go32.mh (XDEPFILES): Delete.
+       * config/i386/cygwin.mh (XDEPFILES): Delete.
+       * config/i386/i386lynx.mh (XDEPFILES): Delete.
+       * config/i386/i386mach.mh (XDEPFILES): Delete.
+       * config/i386/i386v32.mh (XDEPFILES): Delete.
+       * config/i386/linux.mh (XDEPFILES): Delete.
+       * config/i386/nbsdelf.mh (XDEPFILES): Delete.
+       * config/i386/ncr3000.mh (XDEPFILES): Delete.
+       * config/i386/i386mk.mh (NATDEPFILES): Rename XDEPFILES.
+       * config/i386/i386sco.mh (XDEPFILES): Delete.
+       * config/i386/i386v.mh (XDEPFILES): Delete.
+       * config/i386/nbsd.mh (XDEPFILES): Delete.
+       * config/i386/ptx.mh (NATDEPFILES): Rename XDEPFILES.
+       * config/i386/ptx4.mh (NATDEPFILES): Rename XDEPFILES.
+       * config/i386/symmetry.mh (XDEPFILES): Delete.
+       * config/i386/obsd.mh (XDEPFILES): Delete.
+       * config/i386/x86-64linux.mh (XDEPFILES): Delete.
+       * config/ia64/linux.mh (XDEPFILES): Delete.
+       * config/ia64/aix.mh (XDEPFILES): Delete.
+       * config/m68k/apollo68b.mh (XDEPFILES): Delete.
+       * config/m68k/dpx2.mh (XDEPFILES): Delete.
+       * config/m68k/3b1.mh (NATDEPFILES): Rename XDEPFILES.
+       * config/m68k/apollo68v.mh (XDEPFILES): Delete.
+       * config/m68k/hp300bsd.mh (XDEPFILES): Delete.
+       * config/m68k/linux.mh (XDEPFILES): Delete.
+       * config/m68k/m68klynx.mh (XDEPFILES): Delete.
+       * config/m68k/m68kv4.mh (XDEPFILES): Delete.
+       * config/m68k/nbsd.mh (XDEPFILES): Delete.
+       * config/m68k/sun2os3.mh (XDEPFILES): Delete.
+       * config/m68k/sun2os4.mh (XDEPFILES): Delete.
+       * config/m68k/sun3os3.mh (XDEPFILES): Delete.
+       * config/m68k/sun3os4.mh (XDEPFILES): Delete.
+       * config/m88k/delta88.mh (XDEPFILES): Delete.
+       * config/m88k/delta88v4.mh (XDEPFILES): Delete.
+       * config/m88k/m88k.mh (XDEPFILES): Delete.
+       * config/mips/littlemips.mh (NATDEPFILES): Rename XDEPFILES.
+       * config/mips/linux.mh (XDEPFILES): Delete.
+       * config/mips/irix6.mh (XDEPFILES): Delete.
+       * config/mips/irix5.mh (XDEPFILES): Delete.
+       * config/mips/irix4.mh (XDEPFILES): Delete.
+       * config/mips/irix3.mh (XDEPFILES): Delete.
+       * config/mips/decstation.mh (XDEPFILES): Delete.
+       * config/mips/mipsm3.mh (XDEPFILES): Delete.
+       (NATDEPFILES): Move core-aout.o to here.
+       * config/ns32k/nbsd.mh (XDEPFILES): Delete.
+       * config/pa/hpux1020.mh (XDEPFILES): Delete.
+       * config/pa/hppabsd.mh (XDEPFILES): Delete.
+       * config/pa/hppahpux.mh (XDEPFILES): Delete.
+       * config/pa/hpux11w.mh (XDEPFILES): Delete.
+       * config/pa/hppaosf.mh (XDEPFILES): Delete.
+       * config/pa/hpux11.mh (XDEPFILES): Delete.
+       * config/powerpc/aix.mh (XDEPFILES): Delete.
+       * config/powerpc/nbsd.mh (XDEPFILES): Delete.
+       * config/powerpc/linux.mh (XDEPFILES): Delete.
+       * config/romp/rtbsd.mh: Rename XDEPFILES.
+       * config/rs6000/rs6000lynx.mh (XDEPFILES): Delete.
+       * config/rs6000/aix4.mh (XDEPFILES): Delete.
+       * config/rs6000/rs6000.mh (XDEPFILES): Delete.
+       * config/s390/s390.mh (XDEPFILES): Delete.
+       * config/vax/vaxbsd.mh (NATDEPFILES): Rename XDEPFILES.
+       * config/sparc/sun4sol2.mh (XDEPFILES): Delete.
+       * config/sparc/sun4os4.mh (XDEPFILES): Delete.
+       * config/sparc/sparclynx.mh (XDEPFILES): Delete.
+       * config/sparc/nbsdelf.mh (XDEPFILES): Delete.
+       * config/sparc/nbsd.mh (XDEPFILES): Delete.
+       * config/sparc/linux.mh (XDEPFILES): Delete.
+       * config/vax/vaxult.mh (XDEPFILES): Delete.
+       * config/vax/vaxult2.mh (XDEPFILES): Delete.
+       * Makefile.in (DEPFILES): Remove XDEPFILES.
+
+2002-01-17  Andrew Cagney  <ac131313@redhat.com>
+
+       * utils.c (internal_verror): Fix comments, default is yes not no.
+       Update queries to match.  Default to quit and dump core.
+
+2002-01-17  Andrew Cagney  <ac131313@redhat.com>
+
+       * breakpoint.c: Update assuming #if UI_OUT is always true.  Update
+       copyright.
+       * defs.h, event-top.c, gdbcmd.h: Ditto.
+       * infcmd.c, infrun.c, main.c, printcmd.c, remote.c: Ditto.
+       * source.c, stack.c, symfile.c, symtab.c, thread.c: Ditto.
+       * top.c, cli/cli-cmds.c, cli/cli-decode.c: Ditto.
+       * cli/cli-script.c, cli/cli-script.h, cli/cli-setshow.c: Ditto.
+       * mi/ChangeLog, mi/mi-cmd-break.c, mi/mi-cmd-stack.c: Ditto.
+       * mi/mi-main.c:Ditto.
+
+       * stack.c, symfile.c: Update copyright.
+
+2002-01-17  Daniel Jacobowitz  <drow@mvista.com>
+
+       * gdbserver/low-hppabsd.c, gdbserver/low-lynx.c,
+       gdbserver/low-nbsd.c, gdbserver/low-sim.c,
+       gdbserver/low-sparc.c, gdbserver/low-sun3.c,
+       gdbserver/low-linux.c, gdbserver/server.c: Correct copyright notices.
+
+2002-01-17  Daniel Jacobowitz  <drow@mvista.com>
+
+       * gdbserver/low-hppabsd.c (myattach): New function, returning -1.
+       * gdbserver/low-lynx.c (myattach): Likewise.
+       * gdbserver/low-nbsd.c (myattach): Likewise.
+       * gdbserver/low-sim.c (myattach): Likewise.
+       * gdbserver/low-sparc.c (myattach): Likewise.
+       * gdbserver/low-sun3.c (myattach): Likewise.
+
+       * gdbserver/low-linux.c (myattach): New function.
+
+       * gdbserver/server.c (attach_inferior): New function.
+       (main): Handle "--attach".
+
+2002-01-16  Andrew Cagney  <ac131313@redhat.com>
+
+       * MAINTAINERS (language support): Daniel Jacobwitz is C++
+       maintainer.
+
+2002-01-15  Daniel Jacobowitz  <drow@mvista.com>
+
+       * c-typeprint.c (is_type_conversion_operator): Add additional
+       check for non-conversion operators.
+
+2002-01-15  Michael Snyder  <msnyder@redhat.com>
+
+       * linux-proc.c: Add "info proc" command, a la procfs.c.
+       (read_mapping): New function, abstract and re-use code.
+       (linux_find_memory_regions): Use new func read_mapping.
+       (linux_info_proc_cmd): New function, implement "info proc".
+       (_initialize_linux_proc): Add new command "info proc".
+
+2002-01-15  Michael Snyder  <msnyder@redhat.com>
+
+       * symfile.c (generic_load): Use bfd_map_over_sections method
+       instead of manipulating bfd structure members directly.
+       (add_section_size_callback): New function, bfd sections callback
+       used by generic_load.
+       (load_sections_callback): New function, bfd sections callback
+       used by generic_load.
+
+2002-01-15  Elena Zannoni  <ezannoni@redhat.com>
+
+       [Based on work by Jim Blandy]
+       * gdbtypes.h (builtin_type_v16qi, builtin_type_v8hi): Export.
+       (builtin_type_vec128): Export.
+       * gdbtypes.c (builtin_type_v16qi, builtin_type_v8hi): New SIMD
+       types.
+       (builtin_type_vec128): New builtin type for 128 bit vector
+       registers.
+       (build_gdbtypes): Initialize builtin_type_v16qi and
+       builtin_type_v8hi. Create the vec128 register builtin type
+       structure.
+       (build_builtin_type_vec128): New function.
+       (_initialize_gdbtypes): Register builtin_type_v16qi and
+       builtin_type_v8hi with gdbarch. Same for builtin_type_vec128.
+       * rs6000-tdep.c (rs6000_register_virtual_type): Change type of
+       AltiVec register to new builtin type.
+
+2001-01-15  Daniel Jacobowitz  <drow@mvista.com>
+
+       * stabsread.c (read_type): Pass dbx_lookup_type (typenums)
+       to make_cv_type.
+
+2002-01-14  Andrew Cagney  <ac131313@redhat.com>
+
+       * config/pa/tm-hppa.h (DEPRECATED_CLEAN_UP_REGISTER_VALUE): Rename
+       CLEAN_UP_REGISTER_VALUE.
+       * regcache.c (supply_register): Update only call.
+
+2002-01-14  Andrew Cagney  <ac131313@redhat.com>
+
+       * configure.tgt: Mark a29k-*-aout*, a29k-*-coff*, a29k-*-elf*,
+       a29k-*-ebmon*, a29k-*-kern*, a29k-*-none*, a29k-*-udi* and
+       a29k-*-vxworks* targets as obsolete.
+
+2002-01-14  Michael Snyder  <msnyder@redhat.com>
+
+       * linux-proc.c (linux_do_thread_registers): Ignore fpxregs
+       until we can resolve portability issues.
+       * gregset.h: Remove references to fpxregs.
+       * gcore.c (gcore_command): Initialize note_sec to NULL.
+
+2002-01-13  Andrew Cagney  <ac131313@redhat.com>
+
+       * signals.c (target_signal_to_name): Rewrite.  Only use
+       signals[].name when in bounds and non-NULL.
+
+2002-01-13  Andrew Cagney  <ac131313@redhat.com>
+
+       From Petr Ledvina <ledvinap@kae.zcu.cz>:
+       * signals.c (target_signal_to_name): Verify that SIG is within the
+       bounds of the signals array.
+
+2002-01-13  Andrew Cagney  <ac131313@redhat.com>
+
+       * MAINTAINERS: Remove arm-coff and arm-pe from target list.
+
+2002-01-13  Keith Seitz  <keiths@redhat.com>
+
+       * stack.c (print_frame_info_base): Print the frame's pc
+       only if when print_frame_info_listing_hook is not defined.
+
+2002-01-13  Keith Seitz  <keiths@redhat.com>
+
+       * varobj.c (varobj_set_value): Make sure that there were no
+       errors evaluating the object before attempting to set its
+       value.
+       value_cast now properly adjusts VALUE_ADDRESS for baseclasses,
+       so this offset adjustment is no longer necessary.
+       (create_child): Don't set the error flag if the child is
+       a CPLUS_FAKE_CHILD.
+       (value_of_child): If value_fetch_lazy fails, return NULL
+       so that callers will be notified that an error occurred.
+       (c_value_of_variable): Delay check of variable's validity
+       until later. We actually want all structs and unions to have
+       the value "{...}".
+       Do not return "???" for variables which could not be evaluated.
+       This error condition must be returned to the caller so that it
+       can get the error condition from gdb.
+       (cplus_name_of_child): Adjust index for vptr before figuring
+       out the name of the child.
+       (cplus_value_of_child): If a child's (real) parent is not valid,
+       don't even bother trying to give a value for it. Just return
+       an error. Change all instances in this function.
+       (cplus_type_of_child): If our parent is one of the "fake"
+       parents, we need to get at the type of the real parent, and
+       derive the child's true type using this information.
+
+2002-01-13  Andrew Cagney  <ac131313@redhat.com>
+
+       From 2002-01-09 John Marshall <johnm@falch.net>:
+       * CONTRIBUTE, README, TODO: Change sourceware.cygnus.com to
+       sources.redhat.com, and tweak some related URLs which had
+       suffered from linkrot.
+
+2002-01-13  Andrew Cagney  <ac131313@redhat.com>
+
+       From Jeff law:
+       * hppa-tdep.c (hppa_push_arguments): Correct handling of 5-7 byte
+       structures passed in registers.
+
+2002-01-13  Eli Zaretskii  <eliz@is.elta.co.il>
+
+       * go32-nat.c (save_npx) [__DJGPP_MINOR__ < 3]: Remove extraneous
+       white space which prevented compilation.  Reported by DSK
+       <dsk@student.unsw.edu.au>.
+
+2002-01-11  Michael Snyder  <msnyder@redhat.com>
+
+       * symfile.c (build_section_addr_info_from_section_tab):
+       Use bfd access method instead of manipulating bfd directly.
+       (syms_from_objfile): Ditto.
+       (simple_overlay_update_1): Ditto.
+       (simple_overlay_update): Ditto.
+       (generic_load): Ditto.
+       (overlay_unmapped_address): FIXME comment, bfd access methods.
+       (sections_overlap): FIXME comment, bfd access methods.
+       (pc_in_mapped_range): FIXME comment, bfd access methods.
+       (pc_in_unmapped_range): FIXME comment, bfd access methods.
+       (section_is_mapped): FIXME comment, bfd access methods.
+       (section_is_overlay): FIXME comment, bfd access methods.
+
+       * symfile.c (generic_load): Whitespace and long line cleanups.
+       Remove duplicate variable, change several local variables to
+       more appropriate data types.
+       (print_transfer_performance): Use %lu instead of %ld for ulongs.
+
+2002-01-12  Andrew Cagney  <ac131313@redhat.com>
+
+       From Peter Schauer:
+       * language.c (longest_local_hex_string_custom): Use phex_nz to
+       convert NUM to a hex string.
+
+2002-01-12  Elena Zannoni  <ezannoni@redhat.com>
+
+       * sh-tdep.c (sh_gdbarch_init): Move setting of long_bit earlier in
+       the function.
+       Update Copyright year.
+
+2002-01-12  Andrew Cagney  <ac131313@redhat.com>
+
+       * language.c (longest_raw_hex_string): Delete unused function.
+
+2002-01-11  Petr Sorfa  <petrs@caldera.com>
+
+       * MAINTAINERS (write-after-approval): Add myself.
+       * dwarf2read.c (read_tag_string_type): Handling of
+       DW_AT_byte_size.
+       (read_tag_string_type): FORTRAN fix to prevent propagation of
+       first string size.
+       (set_cu_language): Handling of DW_LANG_Fortran95
+
+2002-01-11  Richard Earnshaw  <rearnsha@arm.com>
+
+       * armnbsd-nat.c (fetch_inferior_registers): Change inferior_pid ->
+       GETPID(inferior_ptid).
+       (store_inferior_registers): Likewise.
+
+2002-01-10  Jason Merrill  <jason@redhat.com>
+
+       * dwarf2read.c (decode_locdesc): Implement DW_OP_litn, DW_OP_dup.
+       Fix DW_OP_minus.
+
+2002-01-10  Andrew Cagney  <ac131313@redhat.com>
+
+       * config/djgpp/fnchange.lst: Add renames for bfd/ChangeLog-0001
+       and bfd/elf32-sh-nbsd.c.
+
+2002-01-10  Michael Snyder  <msnyder@redhat.com>
+
+       * NEWS: Mention --pid and corefile/proc-id behavior change.
+
+       * Makefile.in: Add rules for gcore.o and linux-proc.o.
+       * gcore.c: Include cli/cli-decode.h instead of command.h.
+
+       * main.c (captured_main): Add new command line option "--pid".
+       If the second command line argument (following the symbol-file)
+       begins with a digit, try to attach to it before trying to open
+       it as a corefile.
+       (print_gdb_help): Document the "--pid" argument.
+
+2002-01-10  Eli Zaretskii  <eliz@is.elta.co.il>
+
+       * completer.c (command_completer): New function.
+
+       * completer.h <command_completer>: Add prototype.
+
+       * cli/cli-cmds.c (init_cli_cmds): Make command_completer be the
+       completer for the "help" command.
+
+2002-01-09  Jason Merrill  <jason@redhat.com>
+
+       * c-typeprint.c (is_type_conversion_operator): Fix thinko.
+
+2002-01-09  Michael Snyder  <msnyder@redhat.com>
+
+       * i386-linux-nat.c (fill_fpxregset): Make global.
+       (store_fpxregset): Ditto.
+
+       * gregset.h (gdb_fpxregset_t): Define.
+       (supply_fpxregset): Prototype.
+       (fill_fpxregset): Prototype.
+
+       * exec.c (exec_make_note_section): Don't call elfcore_write_prpsinfo.
+
+2002-01-09  Richard Earnshaw  <rearnsha@arm.com>
+
+       * config/arm/arm-tdep.h (arm_software_single_step): Remove PARAMS.
+       * config/arm/nm-nbsd.h (arm_register_u_addr): Likewise.
+       * config/arm/tm-nbsd.h (get_longjmp_target): Likewise.
+
+2002-01-09  Andrew Cagney  <ac131313@redhat.com>
+
+       * MAINTAINERS: Update target maintainer rules so that any
+       Maintainer can approve a tested patch for a maintenance-only
+       target.
+
+2002-01-09  Richard Earnshaw  <rearnsha@arm.com>
+
+       * MAINTAINERS (write-after-approval): Add myself.
+
+       * arm-tdep.c (arm_init_extra_frame_info): Cast NULL argument to
+       IN_SIGTRAMP.
+
+2002-01-08  Michael Snyder  <msnyder@redhat.com>
+
+       * linux-proc.c (child_pid_to_exec_file): Use readlink to get the
+       real name of the executable, rather than the /proc name.
+
+2002-01-03  Michael Snyder  <msnyder@redhat.com>
+
+       Implement a "generate-core-file" command in gdb, save target state.
+       * gcore.c: New file.  Implement new command 'generate-core-file'.
+       Save a corefile image of the current state of the inferior.
+       * linux-proc.c: Add linux-specific code for saving corefiles.
+       * target.h (struct target_ops): Add new target vectors for saving
+       corefiles; to_find_memory_regions and to_make_corefile_notes.
+       (target_find_memory_regions): New macro.
+       (target_make_corefile_notes): New macro.
+       * target.c (update_current_target): Inherit new target methods.
+       (dummy_find_memory_regions): New place-holder method.
+       (dummy_make_corefile_notes): New place-holder method.
+       (init_dummy_target): Initialize new dummy target vectors.
+       * exec.c (exec_set_find_memory_regions): New function.
+       Allow the exec_ops vector for memory regions to be taken over.
+       (exec_make_note_section): New function, target vector method.
+       * defs.h (exec_set_find_memory_regions): Export prototype.
+       * procfs.c (proc_find_memory_regions): New function, corefile method.
+       (procfs_make_note_section): New function, corefile method.
+       (init_procfs_ops): Set new target vector pointers.
+       (find_memory_regions_callback): New function.
+       (procfs_do_thread_registers): New function.
+       (procfs_corefile_thread_callback): New function.
+       * sol-thread.c (sol_find_memory_regions): New function.
+       (sol_make_note_section): New function.
+       (init_sol_thread_ops): Initialize new target vectors.
+       * inftarg.c (inftarg_set_find_memory_regions): New function.
+       Allow to_find_memory_regions vector to be taken over.
+       (inftarg_set_make_corefile_notes): New function.
+       Allow to_make_corefile_notes vector to be taken over.
+       * thread-db.c (thread_db_new_objfile): Don't activate thread-db
+       interface layer if not target_has_execution (may be a corefile).
+       * config/i386/linux.mh: Add gcore.o to NATDEPFILES.
+       * config/sparc/sun4sol2.mh: Ditto.
+       * config/alpha/alpha-linux.mh: Ditto.
+       * config/arm/linux.mh: Ditto.
+       * config/i386/x86-64linux.mh: Ditto.
+       * config/ia64/linux.mh: Ditto.
+       * config/m68k/linux.mh: Ditto.
+       * config/mips/linux.mh: Ditto.
+       * config/powerpc/linux.mh: Ditto.
+       * config/sparc/linux.mh: Ditto.
+
+2002-01-07  Michael Snyder  <msnyder@redhat.com>
+
+       * arm-linux-nat.c: Remove references to regcache.c internal data
+       (registers[] and register_valid[]).
+
+2002-01-07  Michael Snyder  <msnyder@redhat.com>
+
+       * linux-proc.c: New file.  Implement child_pid_to_exec_file,
+       so that attaching to a pid will automatically read the process's
+       symbol file and shlibs.
+       * Makefile.in: Add rule for linux-proc.o.
+       * config/nm-linux.h: Define CHILD_PID_TO_EXEC_FILE.
+       * config/alpha/alpha-linux.mh: Add linux-proc.o to NATDEPFILES.
+       * config/arm/linux.mh: Ditto.
+       * config/i386/linux.mh: Ditto.
+       * config/i386/x86-64linux.mh: Ditto.
+       * config/ia64/linux.mh: Ditto.
+       * config/m68k/linux.mh: Ditto.
+       * config/mips/linux.mh: Ditto.
+       * config/powerpc/linux.mh: Ditto.
+       * config/sparc/linux.mh: Ditto.
+
+2002-01-06  Pierre Muller  <muller@ics.u-strasbg.fr>
+
+       * win32-nat.c: Add i386-tdep.h dependency.
+
+2002-01-07  Michael Snyder  <msnyder@redhat.com>
+
+       * solib.c (info_sharedlibrary_command): Use TARGET_PTR_BIT
+       instead of bfd_get_arch_size.  Don't bail out just because
+       there's no exec_bfd.
+
+       * cp-valprint.c (cp_print_value): FIXME comment, alloca size.
+       * p-valprint.c (pascal_object_print_value): Ditto.
+       * somread.c (som_symtab_read): Ditto.
+       * symfile.c (simple_free_overlay_region_table): Ditto.
+       * valops.c (value_assign): Ditto.
+
+       * tracepoint.c (tracepoint_save_command): From Klee Dienes --
+       use tilde_expand and strerror for opening save-tracepoints file.
+
+       * thread-db.c (thread_db_new_objfile): Indendation fix.
+
+       * infptrace.c (GDB_MAX_ALLOCA): New define.
+       (child_xfer_memory): Use xmalloc/xfree instead of alloca if the
+       size of the buffer exceeds GDB_MAX_ALLOCA (default 1 megabyte,
+       can be overridden with whatever value is appropriate to the host).
+       * infttrace.c (child_xfer_memory): Add FIXME warning about use of
+       alloca to allocate potentially large buffer.
+       * rs6000-nat.c (child_xfer_memory): Ditto.
+       * symm-nat.c (child_xfer_memory): Ditto.
+       * x86-64-linux-nat.c (child_xfer_memory): Ditto.
+
+2002-01-07  Jackie Smith Cashion  <jsmith@redhat.com>
+
+       From Nick Clifton  <nickc@redhat.com>
+       * d10v-tdep.c: Set STACK_START to 0x200bffe.
+
+2002-01-07  Michael Snyder  <msnyder@redhat.com>
+
+       * solib-legacy.c (legacy_svr4_fetch_link_map_offsets):
+       Don't use exec_bfd if it's NULL.
+
+2002-01-06  Mark Kettenis  <kettenis@gnu.org>
+
+       * valops.c (value_arg_coerce): Fix formatting.
+
+2002-01-06  Andrew Cagney  <ac131313@redhat.com>
+
+       * hp-psymtab-read.c: Include "gdb_string.h" instead of <string.h>.
+       * gnu-nat.c: Ditto.
+
+2002-01-06  Andrew Cagney  <ac131313@redhat.com>
+
+       * MAINTAINERS: Note that alpha-dec-osf4.0a, arc-elf, arm-coff,
+       arm-elf, arm-pe, d30v-elf, fr30-elf, h8300hms, h8500hms,
+       i960-coff, m32r-elf, m68k-elf, m88k, mcore-elf, mn10200-elf,
+       ns32k-netbsd, hppa1.1-hp-proelf, v850-elf, vax-dec-vms5.5 and
+       z8k-coff have not been multi-arched.  Update z8k-coff build
+       status.
+
+2002-01-06  Andrew Cagney  <ac131313@redhat.com>
+
+       * MAINTAINERS: Mark a29k target as obsolete.
+       * Makefile.in (a29k-tdep.o, remote-adapt.o, remote-eb.o)
+       (remote-mm.o, remote-udi.o): Obsolete.  Remove references in
+       comments.
+       * NEWS: Note that a29k targets are obsolete.
+       * a29k-tdep.c: Mark as obsolete.
+       * configure.tgt: Mark a29k-*-aout*, a29k-*-coff*, a29k-*-elf*,
+       a29k-*-ebmon*, a29k-*-kern*, a29k-*-none*, a29k-*-udi* and
+       a29k-*-vxworks* targets as obsolete.
+       * remote-adapt.c: Obsolete.
+       * remote-eb.c: Obsolete.
+       * remote-mm.c: Obsolete.
+       * remote-udi.c: Obsolete.
+       * config/a29k/a29k-udi.mt: Obsolete.
+       * config/a29k/a29k.mt: Obsolete.
+       * config/a29k/tm-a29k.h: Obsolete.
+       * config/a29k/tm-vx29k.h: Obsolete.
+       * config/a29k/vx29k.mt: Obsolete.
+
+2002-01-05  Andrew Cagney  <ac131313@redhat.com>
+
+       * rs6000-tdep.c (rs6000_do_registers_info): Replace BIG_ENDIAN
+       with BFD_ENDIAN_BIG.
+
+2002-01-05  Andrew Cagney  <ac131313@redhat.com>
+
+       * configure.in (AC_CHECK_HEADERS): Do not check for <endian.h>.
+       * configure, config.in: Re-generate.
+       * config/vax/xm-vaxbsd.h: Do not include <machine/endian.h>.
+       * defs.h: Do not include <endian.h>.
+
+2002-01-05  Jason Thorpe  <thorpej@wasabisystems.com>
+
+       * acconfig.h (HAVE_PT_GETXMMREGS): New.
+       * config.in: Regenerate.
+       * configure.in: Update copyright years.
+       Add test for PT_GETXMMREGS supplied by <sys/ptrace.h>.
+       * configure: Regenerate.
+       * i386bsd-nat.c: Update copyright years.
+       (fill_gregset): Use regcache_collect.
+       (fetch_inferior_registers): Only fetch integer registers
+       if requested to do so.  Add support for XMM registers
+       using PT_GETXMMREGS.
+       (store_inferior_registers): Only store integer registers
+       if requested to do so.  Add support for XMM registers
+       using PT_SETXMMREGS.
+       * i386nbsd-nat.c (fetch_inferior_registers): Remove.
+       (store_inferior_registers): Remove.
+       (fetch_core_registers): Use supply_gregset and i387_supply_fsave.
+       (fetch_elfcore_registers): New function.
+       (i386nbsd_elfcore_fns): New.
+       (_initialize_i386nbsd_nat): Register i386nbsd_elfcore_fns.
+       * config/i386/nbsd.mh (NATDEPFILES): Add i387-nat.o and
+       i386bsd-nat.o.
+       * config/i386/nbsdelf.mh (NATDEPFILES): Likewise.
+       * config/i386/nbsd.mt (TDEPFILES): Add i386bsd-nat.o.
+       * config/i386/nbsdelf.mt (TDEPFILES): Likewise.
+       * config/i386/tm-nbsd.h: Update copyright years.
+       (HAVE_SSE_REGS): Define.
+       (IN_SIGTRAMP): Define as i386bsd_in_sigtramp.
+       (SIGTRAMP_START): Redefine as i386bsd_sigtramp_start.
+       (SIGTRAMP_END): Redefine as i386bsd_sigtramp_end.
+       (SIGCONTEXT_PC_OFFSET): Remove.
+       (FRAME_SAVED_PC): Define as i386bsd_frame_saved_pc.
+
+2002-01-05  Andrew Cagney  <ac131313@redhat.com>
+
+       * configure.tgt: Remove powerpc-*-macos* target.
+       * config/m68k/xm-mpw.h: Delete file.
+       * config/xm-mpw.h: Delete file.
+       * ser-mac.c: Delete file.
+       * mpw-make.sed: Delete file.
+       * mpw-config.in: Delete file.
+       * mac-xdep.c: Delete file.
+       * mac-gdb.r: Delete file.
+       * mac-defs.h: Delete file.
+       * mac-nat.c: Delete file.
+       * config/powerpc/macos.mh: Delete file.
+       * config/powerpc/macos.mt: Delete file.
+       * config/powerpc/nm-macos.h: Delete file.
+       * config/powerpc/tm-macos.h: Delete file.
+       * source.c (openp, open_source_file): Remove obsolete code.
+       * top.c (gdb_readline): Ditto.
+       * utils.c (query): Ditto.
+       * event-top.c (display_gdb_prompt): Ditto.
+       * Makefile.in (ser-mac.o): Delete obsolete target.
+       * NEWS: Update.
+
+2002-01-04  Andrew Cagney  <ac131313@redhat.com>
+
+       * defs.h (BIG_ENDIAN): Delete macro definition.
+       * a29k-tdep.c, arch-utils.c, arm-tdep.c, ax-gdb.c, ch-exp.c,
+       coffread.c, cris-tdep.c, d10v-tdep.c, d30v-tdep.c, defs.h,
+       findvar.c, infcmd.c, mem-break.c, mips-tdep.c, mn10300-tdep.c,
+       printcmd.c, remote-os9k.c, remote-rdi.c, remote-rdp.c,
+       remote-sim.c, remote.c, rs6000-tdep.c, sh-tdep.c, sparcl-tdep.c,
+       stabsread.c, valops.c, valprint.c, config/a29k/tm-a29k.h,
+       config/a29k/tm-vx29k.h, config/arm/tm-arm.h,
+       config/d30v/tm-d30v.h, config/fr30/tm-fr30.h,
+       config/h8300/tm-h8300.h, config/h8500/tm-h8500.h,
+       config/m32r/tm-m32r.h, config/m68k/tm-m68k.h,
+       config/m88k/tm-m88k.h, config/mips/tm-mips.h, config/pa/tm-hppa.h,
+       config/sparc/tm-sparc.h, config/z8k/tm-z8k.h, mi/mi-cmd-disas.c,
+       mi/mi-main.c: Replace BIG_ENDIAN with BFD_ENDIAN_BIG.
+       * gdbarch.sh: Replace BIG_ENDIAN with BFD_ENDIAN_BIG.
+       * gdbarch.c: Re-generate.
+
+2002-01-04  Daniel Jacobowitz  <drow@mvista.com>
+
+       * thread-db.c (thread_db_new_objfile): Do not enable thread_db
+       for core files.
+
+2002-01-04  Jason Thorpe  <thorpej@wasabisystems.com>
+
+       * config/arm/nbsd.mh (XDEPFILES): Remove ser-tcp.o.
+
+2002-01-04  Andrew Cagney  <ac131313@redhat.com>
+
+       * value.h (value_ptr): Delete typedef.
+
+2002-01-04  Jason Thorpe  <thorpej@wasabisystems.com>
+
+       * i386nbsd-nat.c: Update copyright years.
+       Include i386-tdep.h.
+
+2002-01-04  Elena Zannoni  <ezannoni@redhat.com>
+
+       * stabsread.c: Update copyright years.
+
+       From Debashis Mahata <debashis.mahata@wipro.com>:
+       (read_struct_fields): Deal with Sun C compiler erroneous stab
+       output for structs and unions.
+        Fix PR gdb/269.
+
+2002-01-04  Daniel Jacobowitz  <drow@mvista.com>
+
+       * p-valprint.c: Include "cp-abi.h" for baseclass_offset
+       prototype.
+
+2002-01-04  Daniel Jacobowitz  <drow@mvista.com>
+
+       * cp-abi.c: Fix whitespace.
+       (baseclass_offset): New wrapper function.
+       * cp-abi.h (baseclass_offset): Add prototype.
+       (struct cp_abi_ops): Add baseclass_offset pointer.
+
+       * valops.c (vb_match): Move to...
+       * gnu-v2-abi.c (vb_match): here.
+       * valops.c (baseclass_offset): Move to...
+       * gnu-v2-abi.c (gnuv2_baseclass_offset): here, and rename.
+
+       * gnu-v3-abi.c (gnuv3_baseclass_offset): New function.
+
+       * gnu-v2-abi.c (init_gnuv2_ops): Initialize baseclass_offset.
+       * gnu-v3-abi.c (init_gnuv3_ops): Likewise.
+       * hpacc-abi.c (init_hpacc_ops): Likewise.
+
+2002-01-04  Daniel Jacobowitz  <drow@mvista.com>
+
+       * valops.c (find_overload_match): Accept obj as a
+       reference parameter.  Update it before returning.
+       * value.h (find_overload_match): Update prototype.
+       * eval.c (evaluate_subexp_standard): Pass object to
+       find_overload_match by reference.
+
+2002-01-03  Andrew Cagney  <ac131313@redhat.com>
+
+       * valarith.c: Replace value_ptr with struct value pointer.  Remove
+       register attribute from value declarations.
+       * valops.c: Ditto.
+       * value.h: Ditto.
+       * scm-lang.c (scm_lookup_name): Ditto.
+
+2002-01-03  Michael Snyder  <msnyder@redhat.com>
+
+       Abstract the functionality of iterating over mapped memory
+       regions into a general purpose iterator function.
+       * procfs.c (iterate_over_mappings): New function, general purpose
+       iterator for memory sections.
+       (proc_iterate_over_mappings): Reimplement using iterate_over_mappings.
+       (solib_mappings_callback): New function, callback for above.
+       (info_proc_mappings): Reimpliment using iterate_over_mappings.
+       (info_mappings_callback): New function, callback for above.
+
+       * procfs.c (proc_set_watchpoint): Add cast to suppress warning.
+
+2002-01-01  Mark Kettenis  <kettenis@gnu.org>
+
+       * i386-tdep.h (struct gdbarch_tdep): Add `os_ident' member.
+       * i386-tdep.c: Include "elf-bfd.h".
+       (process_note_abi_tag_sections): New function.
+       (i386_gdbarch_init): Add code to recognize various OS/ABI
+       combinations.
+
+       * maint.c (_initialize_maint_cmds): Add missing \ in
+       string-literal.
+
+For older changes see ChangeLog-2001
+\f
+Local Variables:
+mode: change-log
+left-margin: 8
+fill-column: 74
+version-control: never
+End:
diff --git a/gdb/Makefile.in b/gdb/Makefile.in
new file mode 100644 (file)
index 0000000..ca17a2b
--- /dev/null
@@ -0,0 +1,2595 @@
+# Copyright 1989, 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998,
+# 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+
+# This file is part of GDB.
+
+# 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.
+
+prefix = @prefix@
+exec_prefix = @exec_prefix@
+
+host_alias = @host_alias@
+target_alias = @target_alias@
+program_transform_name = @program_transform_name@
+bindir = @bindir@
+libdir = @libdir@
+tooldir = $(libdir)/$(target_alias)
+
+datadir = @datadir@
+mandir = @mandir@
+man1dir = $(mandir)/man1
+man2dir = $(mandir)/man2
+man3dir = $(mandir)/man3
+man4dir = $(mandir)/man4
+man5dir = $(mandir)/man5
+man6dir = $(mandir)/man6
+man7dir = $(mandir)/man7
+man8dir = $(mandir)/man8
+man9dir = $(mandir)/man9
+infodir = @infodir@
+htmldir = $(prefix)/html
+includedir = @includedir@
+
+# This can be referenced by `INTLDEPS' as computed by CY_GNU_GETTEXT.
+top_builddir = .
+
+SHELL = @SHELL@
+EXEEXT = @EXEEXT@
+
+AWK = @AWK@
+LN_S = @LN_S@
+
+INSTALL = @INSTALL@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@
+INSTALL_DATA = @INSTALL_DATA@
+
+AR = @AR@
+AR_FLAGS = qv
+RANLIB = @RANLIB@
+DLLTOOL = @DLLTOOL@
+WINDRES = @WINDRES@
+MIG = @MIG@
+
+# Flags that describe where you can find the termcap library.
+# This can be overridden in the host Makefile fragment file.
+TERMCAP = @TERM_LIB@
+
+# If you are compiling with GCC, make sure that either 1) You have the
+# fixed include files where GCC can reach them, or 2) You use the
+# -traditional flag.  Otherwise the ioctl calls in inflow.c
+# will be incorrectly compiled.  The "fixincludes" script in the gcc
+# distribution will fix your include files up.
+CC=@CC@
+
+# Directory containing source files.
+srcdir = @srcdir@
+VPATH = @srcdir@
+
+YACC=@YACC@
+
+# This is used to rebuild ada-lex.c from ada-lex.l.  If the program is 
+# not defined, but ada-lex.c is present, compilation will continue,
+# possibly with a warning.
+FLEX = flex
+
+YLWRAP = $(srcdir)/../ylwrap
+
+# where to find makeinfo, preferably one designed for texinfo-2
+MAKEINFO=makeinfo
+
+MAKEHTML = texi2html
+
+MAKEHTMLFLAGS = -glossary -menu -split_chapter
+
+# Set this up with gcc if you have gnu ld and the loader will print out
+# line numbers for undefined references.
+#CC_LD=gcc -static
+CC_LD=$(CC)
+
+# Where is our "include" directory?  Typically $(srcdir)/../include.
+# This is essentially the header file directory for the library
+# routines in libiberty.
+INCLUDE_DIR =  $(srcdir)/../include
+INCLUDE_CFLAGS = -I$(INCLUDE_DIR)
+
+# Where is the "-liberty" library?  Typically in ../libiberty.
+LIBIBERTY = ../libiberty/libiberty.a
+
+# Configured by the --with-mmalloc option to configure.
+MMALLOC = @MMALLOC@
+MMALLOC_CFLAGS = @MMALLOC_CFLAGS@
+
+# Configured by the --with-uiout option to configure.
+UIOUT_CFLAGS = @UIOUT_CFLAGS@
+
+# Where is the BFD library?  Typically in ../bfd.
+BFD_DIR = ../bfd
+BFD = $(BFD_DIR)/libbfd.a
+BFD_SRC = $(srcdir)/$(BFD_DIR)
+BFD_CFLAGS = -I$(BFD_DIR) -I$(BFD_SRC)
+
+# Where is the READLINE library?  Typically in ../readline.
+READLINE_DIR = ../readline
+READLINE = $(READLINE_DIR)/libreadline.a
+READLINE_SRC = $(srcdir)/$(READLINE_DIR)
+READLINE_CFLAGS = -I$(READLINE_SRC)/..
+
+WARN_CFLAGS = @WARN_CFLAGS@
+WERROR_CFLAGS = @WERROR_CFLAGS@
+GDB_WARN_CFLAGS = $(WARN_CFLAGS)
+GDB_WERROR_CFLAGS = $(WERROR_CFLAGS)
+
+# Where is the INTL library?  Typically in ../intl.
+INTL_DIR = ../intl
+INTL = @INTLLIBS@
+INTL_DEPS = @INTLDEPS@
+INTL_SRC = $(srcdir)/$(INTL_DIR)
+INTL_CFLAGS = -I$(INTL_DIR) -I$(INTL_SRC)
+
+# Where is the ICONV library?  This can be empty if libc has iconv.
+LIBICONV = @LIBICONV@
+
+#
+# CLI sub directory definitons
+#
+SUBDIR_CLI_OBS = \
+       cli-dump.o \
+       cli-decode.o cli-script.o cli-cmds.o cli-setshow.o cli-utils.o
+SUBDIR_CLI_SRCS = \
+       cli/cli-dump.c \
+       cli/cli-decode.c cli/cli-script.c cli/cli-cmds.c cli/cli-setshow.c \
+       cli/cli-utils.c
+SUBDIR_CLI_DEPS =
+SUBDIR_CLI_INITS = \
+       $(SUBDIR_CLI_SRCS)
+SUBDIR_CLI_LDFLAGS=
+SUBDIR_CLI_CFLAGS=
+SUBDIR_CLI_ALL=
+SUBDIR_CLI_CLEAN=
+SUBDIR_CLI_INSTALL=
+SUBDIR_CLI_UNINSTALL=
+
+#
+# MI sub directory definitons
+#
+SUBDIR_MI_OBS = \
+       mi-out.o mi-console.o \
+       mi-cmds.o mi-cmd-var.o mi-cmd-break.o mi-cmd-stack.o \
+       mi-cmd-disas.o \
+       mi-main.o mi-parse.o mi-getopt.o
+SUBDIR_MI_SRCS = \
+       mi/mi-out.c mi/mi-console.c \
+       mi/mi-cmds.c \
+       mi/mi-cmd-var.c mi/mi-cmd-break.c mi/mi-cmd-stack.c \
+       mi/mi-cmd-disas.c \
+       mi/mi-main.c mi/mi-parse.c mi/mi-getopt.c
+SUBDIR_MI_DEPS =
+SUBDIR_MI_INITS = \
+       $(SUBDIR_MI_SRCS)
+SUBDIR_MI_LDFLAGS=
+SUBDIR_MI_CFLAGS= \
+       -DMI_OUT=1
+SUBDIR_MI_ALL=
+SUBDIR_MI_CLEAN=
+SUBDIR_MI_INSTALL=
+SUBDIR_MI_UNINSTALL=
+
+#
+# TUI sub directory definitions
+#
+SUBDIR_TUI_OBS = \
+       tui-file.o tui.o tuiData.o tuiSource.o tuiStack.o tuiIO.o \
+       tuiGeneralWin.o tuiLayout.o tuiWin.o tuiCommand.o \
+       tuiDisassem.o tuiSourceWin.o tuiRegs.o tuiDataWin.o \
+       tui-out.o tui-hooks.o
+SUBDIR_TUI_SRCS = \
+       tui/tui-file.c tui/tui.c tui/tuiData.c tui/tuiSource.c \
+       tui/tuiStack.c tui/tuiIO.c \
+       tui/tuiGeneralWin.c tui/tuiLayout.c \
+       tui/tuiWin.c tui/tuiCommand.c \
+       tui/tuiDisassem.c tui/tuiSourceWin.c \
+       tui/tuiRegs.c tui/tuiDataWin.c tui/tui-out.c tui/tui-hooks.c
+SUBDIR_TUI_DEPS =
+SUBDIR_TUI_INITS = \
+       $(SUBDIR_TUI_SRCS)
+SUBDIR_TUI_LDFLAGS=
+SUBDIR_TUI_CFLAGS= \
+       -DTUI=1 -I${srcdir}/tui
+SUBDIR_TUI_ALL=
+SUBDIR_TUI_CLEAN=
+SUBDIR_TUI_INSTALL=
+SUBDIR_TUI_UNINSTALL=
+
+
+
+# Opcodes currently live in one of two places.  Either they are in the
+# opcode library, typically ../opcodes, or they are in a header file
+# in INCLUDE_DIR.
+# Where is the "-lopcodes" library, with (some of) the opcode tables and
+# disassemblers?
+OPCODES_DIR = ../opcodes
+OPCODES_SRC = $(srcdir)/$(OPCODES_DIR)
+OPCODES = $(OPCODES_DIR)/libopcodes.a
+# Where are the other opcode tables which only have header file
+# versions?
+OP_INCLUDE = $(INCLUDE_DIR)/opcode
+OPCODES_CFLAGS = -I$(OP_INCLUDE)
+
+# The simulator is usually nonexistent; targets that include one
+# should set this to list all the .o or .a files to be linked in.
+SIM =
+
+WIN32LIBS = @WIN32LIBS@
+
+# Where is the TCL library?  Typically in ../tcl.
+LIB_INSTALL_DIR = $(libdir)
+# This variable is needed when doing dynamic linking.
+LIB_RUNTIME_DIR = $(libdir)
+TCL = @TCL_LD_SEARCH_FLAGS@ @TCL_BUILD_LIB_SPEC@
+TCL_CFLAGS = @TCLHDIR@
+TCL_DEPS = @TCL_DEPS@
+GDBTKLIBS = @GDBTKLIBS@
+# Extra flags that the GDBTK files need:
+GDBTK_CFLAGS = @GDBTK_CFLAGS@
+
+# Where is the TK library?  Typically in ../tk.
+TK = @TK_BUILD_LIB_SPEC@
+TK_CFLAGS = @TKHDIR@ @TK_BUILD_INCLUDES@
+TK_DEPS = @TK_DEPS@
+
+# Where is Itcl?  Typically in ../itcl/itcl.
+ITCL_CFLAGS = @ITCLHDIR@
+ITCL = @ITCLLIB@
+ITCL_DEPS = @ITCL_DEPS@ 
+
+# Where is Itk?  Typically in ../itcl/itk.
+ITK_CFLAGS = @ITKHDIR@
+ITK = @ITKLIB@
+ITK_DEPS = @ITK_DEPS@ 
+
+# Where is Tix?  Typically in ../tix.
+TIX_CFLAGS = @TIXHDIR@
+TIX = @TIXLIB@
+TIX_DEPS = @TIX_DEPS@
+
+X11_CFLAGS = @TK_XINCLUDES@
+X11_LDFLAGS =
+X11_LIBS =
+
+WIN32LDAPP = @WIN32LDAPP@
+
+LIBGUI = @LIBGUI@
+GUI_CFLAGS_X = @GUI_CFLAGS_X@
+IDE_CFLAGS=$(GUI_CFLAGS_X) $(IDE_CFLAGS_X)
+
+# The version of gdbtk we're building. This should be kept
+# in sync with GDBTK_VERSION and friends in gdbtk.h.
+GDBTK_VERSION = 1.0
+GDBTK_LIBRARY = $(datadir)/insight$(GDBTK_VERSION)
+
+# Gdbtk requires an absolute path to the source directory or
+# the testsuite won't run properly.
+GDBTK_SRC_DIR = @GDBTK_SRC_DIR@
+
+SUBDIR_GDBTK_OBS = \
+       gdbtk.o gdbtk-bp.o gdbtk-cmds.o gdbtk-hooks.o \
+       gdbtk-register.o gdbtk-stack.o gdbtk-varobj.o gdbtk-wrapper.o
+SUBDIR_GDBTK_SRCS = \
+       gdbtk/generic/gdbtk.c gdbtk/generic/gdbtk-bp.c \
+       gdbtk/generic/gdbtk-cmds.c gdbtk/generic/gdbtk-hooks.c \
+       gdbtk/generic/gdbtk-register.c gdbtk/generic/gdbtk-stack.c \
+       gdbtk/generic/gdbtk-varobj.c gdbtk/generic/gdbtk-wrapper.c
+SUBDIR_GDBTK_DEPS = \
+       $(LIBGUI) $(ITCL_DEPS) $(ITK_DEPS) $(TIX_DEPS) $(TK_DEPS) $(TCL_DEPS)
+SUBDIR_GDBTK_INITS = gdbtk/generic/gdbtk.c
+SUBDIR_GDBTK_LDFLAGS=
+SUBDIR_GDBTK_CFLAGS= -DGDBTK
+SUBDIR_GDBTK_ALL=
+SUBDIR_GDBTK_CLEAN=
+SUBDIR_GDBTK_INSTALL= install-gdbtk
+SUBDIR_GDBTK_UNINSTALL= 
+
+CONFIG_OBS= @CONFIG_OBS@
+CONFIG_LIB_OBS= @CONFIG_LIB_OBS@
+CONFIG_SRCS= @CONFIG_SRCS@
+CONFIG_DEPS= @CONFIG_DEPS@
+CONFIG_INITS= @CONFIG_INITS@
+CONFIG_LDFLAGS = @CONFIG_LDFLAGS@
+ENABLE_CFLAGS= @ENABLE_CFLAGS@
+CONFIG_ALL= @CONFIG_ALL@
+CONFIG_CLEAN= @CONFIG_CLEAN@
+CONFIG_CLEAN= @CONFIG_CLEAN@
+CONFIG_INSTALL = @CONFIG_INSTALL@
+CONFIG_UNINSTALL = @CONFIG_UNINSTALL@
+
+# -I. for config files.
+# -I$(srcdir) for gdb internal headers.
+# -I$(srcdir)/config for more generic config files.
+
+# It is also possible that you will need to add -I/usr/include/sys if
+# your system doesn't have fcntl.h in /usr/include (which is where it
+# should be according to Posix).
+DEFS = @DEFS@
+GDB_CFLAGS = -I. -I$(srcdir) -I$(srcdir)/config -DLOCALEDIR="\"$(prefix)/share/locale\"" $(DEFS)
+
+# M{H,T}_CFLAGS, if defined, have host- and target-dependent CFLAGS
+# from the config directory.
+GLOBAL_CFLAGS = $(MT_CFLAGS) $(MH_CFLAGS)
+#PROFILE_CFLAGS = -pg
+
+# CFLAGS is specifically reserved for setting from the command line
+# when running make.  I.E.  "make CFLAGS=-Wmissing-prototypes".
+CFLAGS = @CFLAGS@
+
+# Need to pass this to testsuite for "make check".  Probably should be
+# consistent with top-level Makefile.in and gdb/testsuite/Makefile.in
+# so "make check" has the same result no matter where it is run.
+CXXFLAGS = -g -O
+
+# INTERNAL_CFLAGS is the aggregate of all other *CFLAGS macros.
+INTERNAL_WARN_CFLAGS = \
+       $(CFLAGS) $(GLOBAL_CFLAGS) $(PROFILE_CFLAGS) \
+       $(GDB_CFLAGS) $(OPCODES_CFLAGS) $(READLINE_CFLAGS) \
+       $(BFD_CFLAGS) $(MMALLOC_CFLAGS) $(INCLUDE_CFLAGS) \
+       $(INTL_CFLAGS) $(ENABLE_CFLAGS) $(UIOUT_CFLAGS) \
+       $(GDB_WARN_CFLAGS)
+INTERNAL_CFLAGS = $(INTERNAL_WARN_CFLAGS) $(GDB_WERROR_CFLAGS)
+
+# LDFLAGS is specifically reserved for setting from the command line
+# when running make.
+LDFLAGS = @LDFLAGS@
+
+# Profiling options need to go here to work.
+# I think it's perfectly reasonable for a user to set -pg in CFLAGS
+# and have it work; that's why CFLAGS is here.
+INTERNAL_LDFLAGS = $(CFLAGS) $(GLOBAL_CFLAGS) $(PROFILE_CFLAGS) $(MH_LDFLAGS) $(LDFLAGS) $(CONFIG_LDFLAGS) @HLDFLAGS@
+HLDENV = @HLDENV@
+
+# If your system is missing alloca(), or, more likely, it's there but
+# it doesn't work, then refer to libiberty.
+
+# Libraries and corresponding dependencies for compiling gdb.
+# {X,T}M_CLIBS, defined in *config files, have host- and target-dependent libs.
+# TERMCAP comes after readline, since readline depends on it.
+# MMALLOC comes after anything else that might want an allocation function.
+# LIBIBERTY appears twice on purpose.
+# If you have the Cygnus libraries installed,
+# you can use 'CLIBS=$(INSTALLED_LIBS)' 'CDEPS='
+INSTALLED_LIBS=-lbfd -lreadline -lopcodes -liberty \
+       $(TERMCAP) $(XM_CLIBS) $(TM_CLIBS) $(NAT_CLIBS) $(GDBTKLIBS) @LIBS@ \
+       -lmmalloc -lintl -liberty
+CLIBS = $(SIM) $(BFD) $(READLINE) $(OPCODES) $(INTL) $(LIBIBERTY) \
+       $(TERMCAP) $(XM_CLIBS) $(TM_CLIBS) $(NAT_CLIBS) $(GDBTKLIBS) @LIBS@ \
+       $(LIBICONV) \
+       $(MMALLOC) $(LIBIBERTY) $(WIN32LIBS)
+CDEPS = $(XM_CDEPS) $(TM_CDEPS) $(NAT_CDEPS) $(SIM) $(BFD) $(READLINE) \
+       $(OPCODES) $(MMALLOC) $(INTL_DEPS) $(LIBIBERTY) $(CONFIG_DEPS)
+
+ADD_FILES = $(XM_ADD_FILES) $(TM_ADD_FILES) $(NAT_ADD_FILES)
+ADD_DEPS = $(XM_ADD_FILES) $(TM_ADD_FILES) $(NAT_ADD_FILES)
+
+DIST=gdb
+
+LINT=/usr/5bin/lint
+LINTFLAGS= $(GDB_CFLAGS) $(OPCODES_CFLAGS) $(READLINE_CFLAGS) \
+       $(BFD_CFLAGS) $(MMALLOC_CFLAGS) $(INCLUDE_CFLAGS) \
+       $(INTL_CFLAGS)
+
+RUNTEST = `if [ -f $${rootsrc}/../dejagnu/runtest ] ; then \
+               echo $${rootsrc}/../dejagnu/runtest ; else echo runtest; \
+          fi`
+
+RUNTESTFLAGS=
+
+# This is ser-unix.o for any system which supports a v7/BSD/SYSV/POSIX
+# interface to the serial port.  Hopefully if get ported to OS/2, VMS,
+# etc., then there will be (as part of the C library or perhaps as
+# part of libiberty) a POSIX interface.  But at least for now the
+# host-dependent makefile fragment might need to use something else
+# besides ser-unix.o
+SER_HARDWIRE = @SER_HARDWIRE@
+
+# The `remote' debugging target is supported for most architectures,
+# but not all (e.g. 960)
+REMOTE_OBS = remote.o dcache.o remote-utils.o tracepoint.o ax-general.o ax-gdb.o
+
+# This is remote-sim.o if a simulator is to be linked in.
+SIM_OBS =
+
+ANNOTATE_OBS = annotate.o
+
+# Host and target-dependent makefile fragments come in here.
+@host_makefile_frag@
+@target_makefile_frag@
+# End of host and target-dependent makefile fragments
+
+# Possibly ignore the simulator.  If the simulator is being ignored, 
+# these expand into SIM= and SIM_OBJ=, overriding the entries from 
+# target_makefile_frag
+#
+@IGNORE_SIM@
+@IGNORE_SIM_OBS@
+
+FLAGS_TO_PASS = \
+       "prefix=$(prefix)" \
+       "exec_prefix=$(exec_prefix)" \
+       "infodir=$(infodir)" \
+       "libdir=$(libdir)" \
+       "mandir=$(mandir)" \
+       "datadir=$(datadir)" \
+       "includedir=$(includedir)" \
+       "against=$(against)" \
+       "AR=$(AR)" \
+       "AR_FLAGS=$(AR_FLAGS)" \
+       "CC=$(CC)" \
+       "CFLAGS=$(CFLAGS)" \
+       "CXX=$(CXX)" \
+       "CXXFLAGS=$(CXXFLAGS)" \
+       "DLLTOOL=$(DLLTOOL)" \
+       "RANLIB=$(RANLIB)" \
+       "MAKEINFO=$(MAKEINFO)" \
+       "MAKEHTML=$(MAKEHTML)" \
+       "MAKEHTMLFLAGS=$(MAKEHTMLFLAGS)" \
+       "INSTALL=$(INSTALL)" \
+       "INSTALL_PROGRAM=$(INSTALL_PROGRAM)" \
+       "INSTALL_DATA=$(INSTALL_DATA)" \
+       "RUNTEST=$(RUNTEST)" \
+       "RUNTESTFLAGS=$(RUNTESTFLAGS)"
+
+# Flags that we pass when building the testsuite.
+
+# empty for native, $(target_alias)/ for cross
+target_subdir = @target_subdir@
+
+CC_FOR_TARGET = ` \
+  if [ -f $${rootme}/../gcc/xgcc ] ; then \
+    if [ -f $${rootme}/../$(target_subdir)newlib/Makefile ] ; then \
+      echo $${rootme}/../gcc/xgcc -B$${rootme}/../gcc/ -idirafter $${rootme}/$(target_subdir)newlib/targ-include -idirafter $${rootsrc}/../$(target_subdir)newlib/libc/include -nostdinc -B$${rootme}/../$(target_subdir)newlib/; \
+    else \
+      echo $${rootme}/../gcc/xgcc -B$${rootme}/../gcc/; \
+    fi; \
+  else \
+    if [ "$(host_canonical)" = "$(target_canonical)" ] ; then \
+      echo $(CC); \
+    else \
+      t='$(program_transform_name)'; echo gcc | sed -e '' $$t; \
+    fi; \
+  fi`
+
+CXX = gcc
+CXX_FOR_TARGET = ` \
+  if [ -f $${rootme}/../gcc/xgcc ] ; then \
+    if [ -f $${rootme}/../$(target_subdir)newlib/Makefile ] ; then \
+      echo $${rootme}/../gcc/xgcc -B$${rootme}/../gcc/ -idirafter $${rootme}/$(target_subdir)newlib/targ-include -idirafter $${rootsrc}/../$(target_subdir)newlib/libc/include -nostdinc -B$${rootme}/../$(target_subdir)newlib/; \
+    else \
+      echo $${rootme}/../gcc/xgcc -B$${rootme}/../gcc/; \
+    fi; \
+  else \
+    if [ "$(host_canonical)" = "$(target_canonical)" ] ; then \
+      echo $(CXX); \
+    else \
+      t='$(program_transform_name)'; echo gcc | sed -e '' $$t; \
+    fi; \
+  fi`
+
+# OBSOLETE CHILLFLAGS = $(CFLAGS)
+# OBSOLETE CHILL = gcc
+# OBSOLETE CHILL_FOR_TARGET = ` \
+# OBSOLETE   if [ -f $${rootme}/../gcc/Makefile ] ; then \
+# OBSOLETE     echo $${rootme}/../gcc/xgcc -B$${rootme}/../gcc/ -L$${rootme}/../gcc/ch/runtime/; \
+# OBSOLETE   else \
+# OBSOLETE     if [ "$(host_canonical)" = "$(target_canonical)" ] ; then \
+# OBSOLETE       echo $(CC); \
+# OBSOLETE     else \
+# OBSOLETE       t='$(program_transform_name)'; echo gcc | sed -e '' $$t; \
+# OBSOLETE     fi; \
+# OBSOLETE   fi`
+# OBSOLETE CHILL_LIB = ` \
+# OBSOLETE   if [ -f $${rootme}/../gcc/ch/runtime/libchill.a ] ; then \
+# OBSOLETE     echo $${rootme}/../gcc/ch/runtime/chillrt0.o \
+# OBSOLETE       $${rootme}/../gcc/ch/runtime/libchill.a; \
+# OBSOLETE   else \
+# OBSOLETE       echo -lchill; \
+# OBSOLETE   fi`
+
+# The use of $$(x_FOR_TARGET) reduces the command line length by not
+# duplicating the lengthy definition.
+TARGET_FLAGS_TO_PASS = \
+       "prefix=$(prefix)" \
+       "exec_prefix=$(exec_prefix)" \
+       "against=$(against)" \
+       'CC=$$(CC_FOR_TARGET)' \
+       "CC_FOR_TARGET=$(CC_FOR_TARGET)" \
+       "CFLAGS=$(CFLAGS)" \
+       'CXX=$$(CXX_FOR_TARGET)' \
+       "CXX_FOR_TARGET=$(CXX_FOR_TARGET)" \
+       "CXXFLAGS=$(CXXFLAGS)" \
+       "INSTALL=$(INSTALL)" \
+       "INSTALL_PROGRAM=$(INSTALL_PROGRAM)" \
+       "INSTALL_DATA=$(INSTALL_DATA)" \
+       "MAKEINFO=$(MAKEINFO)" \
+       "MAKEHTML=$(MAKEHTML)" \
+       "RUNTEST=$(RUNTEST)" \
+       "RUNTESTFLAGS=$(RUNTESTFLAGS)"
+
+# All source files that go into linking GDB.
+# Links made at configuration time should not be specified here, since
+# SFILES is used in building the distribution archive.
+
+SFILES = ada-exp.y ada-lang.c ada-typeprint.c ada-valprint.c ada-tasks.c \
+       ax-general.c ax-gdb.c bcache.c blockframe.c breakpoint.c \
+       charset.c \
+       buildsym.c c-exp.y c-lang.c c-typeprint.c c-valprint.c \
+       coffread.c \
+       complaints.c completer.c corefile.c cp-valprint.c dbxread.c \
+       demangle.c dwarfread.c dwarf2read.c elfread.c environ.c eval.c \
+       event-loop.c event-top.c \
+       expprint.c f-exp.y f-lang.c f-typeprint.c f-valprint.c \
+       findvar.c regcache.c gdbarch.c arch-utils.c gdbtypes.c osabi.c \
+       inf-loop.c infcmd.c inflow.c infrun.c language.c \
+       kod.c kod-cisco.c \
+       ui-out.c cli-out.c \
+       varobj.c wrapper.c \
+       jv-exp.y jv-lang.c jv-valprint.c jv-typeprint.c \
+       m2-exp.y m2-lang.c m2-typeprint.c m2-valprint.c main.c maint.c \
+       memattr.c mem-break.c minsyms.c mipsread.c nlmread.c objfiles.c \
+       p-exp.y p-lang.c p-typeprint.c p-valprint.c parse.c \
+       macrotab.c macroexp.c macrocmd.c macroscope.c \
+       printcmd.c remote.c scm-exp.c scm-lang.c \
+       scm-valprint.c source.c stabsread.c stack.c symfile.c \
+       symmisc.c symtab.c linespec.c target.c thread.c top.c tracepoint.c \
+       typeprint.c utils.c valarith.c valops.c valprint.c values.c \
+       serial.c ser-unix.c mdebugread.c \
+       tui/tui.c tui/tui.h tui/tuiCommand.c tui/tuiCommand.h \
+       tui/tuiData.c tui/tuiData.h tui/tuiDataWin.c tui/tuiDataWin.h \
+       tui/tuiDisassem.c tui/tuiDisassem.h tui/tuiGeneralWin.c \
+       tui/tuiGeneralWin.h tui/tuiIO.c tui/tuiIO.h tui/tuiLayout.c \
+       tui/tuiLayout.h tui/tuiRegs.c tui/tuiRegs.h tui/tuiSource.c \
+       tui/tuiSource.h tui/tuiSourceWin.c tui/tuiSourceWin.h \
+       tui/tuiStack.c tui/tuiStack.h tui/tuiWin.c tui/tuiWin.h \
+       tui/tui-file.h tui/tui-file.c tui/tui-out.c tui/tui-hooks.c \
+       ui-file.h ui-file.c \
+       frame.c doublest.c \
+       builtin-regs.c std-regs.c \
+       gnu-v2-abi.c gnu-v3-abi.c hpacc-abi.c cp-abi.c cp-support.c
+
+LINTFILES = $(SFILES) $(YYFILES) $(CONFIG_SRCS) init.c
+
+# "system" headers.  Using these in dependencies is a rather personal
+# choice. (-rich, summer 1993)
+# (Why would we not want to depend on them?  If one of these changes in a 
+# non-binary-compatible way, it is a real pain to remake the right stuff
+# without these dependencies -kingdon, 13 Mar 1994)
+aout_aout64_h =        $(INCLUDE_DIR)/aout/aout64.h
+aout_stabs_gnu_h =     $(INCLUDE_DIR)/aout/stabs_gnu.h
+getopt_h =     $(INCLUDE_DIR)/getopt.h
+floatformat_h =        $(INCLUDE_DIR)/floatformat.h
+bfd_h =                $(BFD_DIR)/bfd.h
+callback_h =   $(INCLUDE_DIR)/gdb/callback.h
+coff_sym_h =   $(INCLUDE_DIR)/coff/sym.h
+coff_symconst_h =      $(INCLUDE_DIR)/coff/symconst.h
+coff_ecoff_h = $(INCLUDE_DIR)/coff/ecoff.h
+dis_asm_h =    $(INCLUDE_DIR)/dis-asm.h 
+elf_sh_h =     $(INCLUDE_DIR)/elf/sh.h
+elf_bfd_h =    $(BFD_SRC)/elf-bfd.h
+libaout_h =    $(BFD_SRC)/libaout.h
+remote_sim_h = $(INCLUDE_DIR)/gdb/remote-sim.h
+demangle_h =    $(INCLUDE_DIR)/demangle.h
+obstack_h =     $(INCLUDE_DIR)/obstack.h
+opcode_m68hc11_h = $(INCLUDE_DIR)/opcode/m68hc11.h
+sh_opc_h =     $(OPCODES_SRC)/sh-opc.h
+gdb_sim_arm_h =        $(INCLUDE_DIR)/gdb/sim-arm.h
+gdb_sim_d10v_h = $(INCLUDE_DIR)/gdb/sim-d10v.h
+gdb_sim_sh_h = $(INCLUDE_DIR)/gdb/sim-sh.h
+splay_tree_h =  $(INCLUDE_DIR)/splay-tree.h
+
+readline_headers = \
+       $(READLINE_SRC)/chardefs.h \
+       $(READLINE_SRC)/history.h \
+       $(READLINE_SRC)/keymaps.h \
+       $(READLINE_SRC)/readline.h
+
+xm_h =         @xm_h@
+tm_h =         @tm_h@
+nm_h =         @nm_h@
+
+#
+# gdb/ header files
+#
+
+acconfig_h = acconfig.h
+ada_lang_h = ada-lang.h $(value_h) $(gdbtypes_h)
+alpha_tdep_h = alpha-tdep.h $(osabi_h)
+alphabsd_tdep_h = alphabsd-tdep.h
+annotate_h = annotate.h $(symtab_h) $(gdbtypes_h)
+arch_utils_h = arch-utils.h
+arm_tdep_h = arm-tdep.h $(osabi_h)
+ax_gdb_h = ax-gdb.h
+ax_h = ax.h $(doublest_h)
+bcache_h = bcache.h
+breakpoint_h = breakpoint.h $(frame_h) $(value_h) $(gdb_events_h)
+buildsym_h = buildsym.h
+builtin_regs_h = builtin-regs.h
+c_lang_h = c-lang.h $(value_h) $(macroexp_h)
+call_cmds_h = call-cmds.h
+ch_lang_h = ch-lang.h
+cli_out_h = cli-out.h
+coff_solib_h = coff-solib.h
+command_h = command.h
+complaints_h = complaints.h
+completer_h = completer.h
+cp_abi_h = cp-abi.h
+cp_support_h = cp-support.h
+dcache_h = dcache.h
+defs_h = defs.h $(config_h) $(gdb_locale_h) $(gdb_signals_h) $(ansidecl_h) \
+       $(libiberty_h) $(progress_h) $(bfd_h) $(tui_h) $(ui_file_h) $(xm_h) \
+       $(nm_h) $(tm_h) $(fopen_same_h) $(gdbarch_h) $(arch_utils_h)
+doublest_h = doublest.h $(floatformat_h)
+dst_h = dst.h
+dwarf2cfi_h = dwarf2cfi.h
+environ_h = environ.h
+event_loop_h = event-loop.h
+event_top_h = event-top.h
+expression_h = expression.h $(symtab_h) $(doublest_h)
+f_lang_h = f-lang.h
+frame_h = frame.h
+gdb_events_h = gdb-events.h
+gdb_stabs_h = gdb-stabs.h
+gdb_h = gdb.h
+gdb_assert_h = gdb_assert.h
+gdb_dirent_h = gdb_dirent.h
+gdb_locale_h = gdb_locale.h
+gdb_obstack_h = gdb_obstack.h $(obstack_h)
+gdb_proc_service_h = gdb_proc_service.h $(gregset_h)
+gdb_regex_h = gdb_regex.h $(xregex_h)
+gdb_stat_h = gdb_stat.h
+gdb_string_h = gdb_string.h
+gdb_thread_db_h = gdb_thread_db.h
+gdb_vfork_h = gdb_vfork.h
+gdb_wait_h = gdb_wait.h
+gdbarch_h = gdbarch.h $(dis_asm_h) $(value_h) $(inferior_h)
+gdbcmd_h = gdbcmd.h $(command_h) $(ui_out_h)
+gdbcore_h = gdbcore.h $(bfd_h)
+gdbthread_h = gdbthread.h $(breakpoint_h)
+gdbtypes_h = gdbtypes.h
+gnu_nat_h = gnu-nat.h
+gregset_h = gregset.h
+i386_linux_tdep_h = i386-linux-tdep.h
+i386_tdep_h = i386-tdep.h $(osabi_h)
+i387_tdep_h = i387-tdep.h
+inf_loop_h = inf-loop.h
+inferior_h = inferior.h $(breakpoint_h) $(target_h)
+jv_lang_h = jv-lang.h
+kod_h = kod.h
+language_h = language.h
+linespec_h = linespec.h
+m2_lang_h = m2-lang.h
+macroexp_h = macroexp.h
+macroscope_h = macroscope.h $(macrotab_h) $(symtab_h)
+macrotab_h = macrotab.h
+memattr_h = memattr.h
+minimon_h = minimon.h
+mipsnbsd_tdep_h = mipsnbsd-tdep.h
+monitor_h = monitor.h
+nbsd_tdep_h = nbsd-tdep.h
+ns32k_tdep_h = ns32k-tdep.h $(osabi_h)
+objfiles_h = objfiles.h $(gdb_obstack_h) $(symfile_h)
+ocd_h = ocd.h
+osabi_h = osabi.h
+p_lang_h = p-lang.h
+pa64solib_h = pa64solib.h
+parser_defs_h = parser-defs.h $(doublest_h)
+ppc_tdep_h = ppc-tdep.h $(osabi_h)
+ppcnbsd_tdep_h = ppcnbsd-tdep.h
+proc_utils_h = proc-utils.h
+regcache_h = regcache.h
+remote_utils_h = remote-utils.h $(target_h)
+remote_h = remote.h
+scm_lang_h = scm-lang.h $(scm_tags_h)
+scm_tags_h = scm-tags.h
+ser_unix_h = ser-unix.h
+serial_h = serial.h
+sh_tdep_h = sh-tdep.h $(osabi_h)
+shnbsd_tdep_h = shnbsd-tdep.h
+sim_regno_h = sim-regno.h
+solib_svr4_h = solib-svr4.h
+solib_h = solib.h
+solist_h = solist.h
+somsolib_h = somsolib.h
+source_h = source.h
+sparcnbsd_tdep_h = sparcnbsd-tdep.h
+srec_h = srec.h
+stabsread_h = stabsread.h
+symfile_h = symfile.h
+symtab_h = symtab.h
+target_h = target.h $(bfd_h) $(symtab_h) $(dcache_h) $(memattr_h)
+terminal_h = terminal.h
+top_h = top.h
+tracepoint_h = tracepoint.h
+typeprint_h = typeprint.h
+ui_file_h = ui-file.h
+ui_out_h = ui-out.h
+valprint_h = valprint.h
+value_h = value.h $(doublest_h) $(symtab_h) $(gdbtypes_h) $(expression_h)
+varobj_h = varobj.h $(symtab_h) $(gdbtypes_h)
+vax_tdep_h = vax-tdep.h $(osabi_h)
+version_h = version.h
+wince_stub_h = wince-stub.h
+wrapper_h = wrapper.h $(gdb_h)
+x86_64_tdep_h = x86-64-tdep.h $(i386_tdep_h)
+xcoffsolib_h = xcoffsolib.h
+xmodem_h = xmodem.h
+
+#
+# gdb/cli/ headers
+#
+
+cli_cmds_h = $(srcdir)/cli/cli-cmds.h
+cli_decode_h = $(srcdir)/cli/cli-decode.h $(gdb_regex_h) $(command_h)
+cli_dump_h = $(srcdir)/cli/cli-dump.h
+cli_script_h = $(srcdir)/cli/cli-script.h
+cli_setshow_h = $(srcdir)/cli/cli-setshow.h
+cli_utils_h = $(srcdir)/cli/cli-utils.h
+
+#
+# gdb/mi/ headers
+#
+
+mi_cmds_h = $(srcdir)/mi/mi-cmds.h
+mi_console_h = $(srcdir)/mi/mi-console.h
+mi_getopt_h = $(srcdir)/mi/mi-getopt.h
+mi_out_h = $(srcdir)/mi/mi-out.h
+mi_parse_h = $(srcdir)/mi/mi-parse.h
+
+#
+# gdb/tui/ headers
+#
+
+tui_file_h = $(srcdir)/tui/tui-file.h
+tui_h = $(srcdir)/tui/tui.h $(ansidecl_h)
+tuiCommand_h = $(srcdir)/tui/tuiCommand.h
+tuiData_h = $(srcdir)/tui/tuiData.h
+tuiDataWin_h = $(srcdir)/tui/tuiDataWin.h
+tuiDisassem_h = $(srcdir)/tui/tuiDisassem.h
+tuiGeneralWin_h = $(srcdir)/tui/tuiGeneralWin.h
+tuiIO_h = $(srcdir)/tui/tuiIO.h
+tuiLayout_h = $(srcdir)/tui/tuiLayout.h
+tuiRegs_h = $(srcdir)/tui/tuiRegs.h
+tuiSource_h = $(srcdir)/tui/tuiSource.h $(defs_h)
+tuiSourceWin_h = $(srcdir)/tui/tuiSourceWin.h
+tuiStack_h = $(srcdir)/tui/tuiStack.h
+tuiWin_h = $(srcdir)/tui/tuiWin.h
+
+charset_h =    charset.h
+
+# Header files that need to have srcdir added.  Note that in the cases
+# where we use a macro like $(gdbcmd_h), things are carefully arranged
+# so that each .h file is listed exactly once (M-x tags-search works
+# wrong if TAGS has files twice).  Because this is tricky to get
+# right, it is probably easiest just to list .h files here directly.
+
+HFILES_NO_SRCDIR = bcache.h buildsym.h call-cmds.h coff-solib.h defs.h \
+       environ.h $(gdbcmd_h) gdb.h gdbcore.h \
+       gdb-stabs.h $(inferior_h) language.h minimon.h monitor.h \
+       objfiles.h parser-defs.h serial.h solib.h \
+       symfile.h stabsread.h target.h terminal.h typeprint.h xcoffsolib.h \
+       macrotab.h macroexp.h macroscope.h \
+       c-lang.h f-lang.h \
+       jv-lang.h \
+       m2-lang.h  p-lang.h \
+       complaints.h valprint.h \
+       nindy-share/b.out.h \
+       nindy-share/block_io.h nindy-share/coff.h \
+       nindy-share/env.h nindy-share/stop.h \
+       vx-share/dbgRpcLib.h vx-share/ptrace.h vx-share/vxTypes.h \
+       vx-share/vxWorks.h vx-share/wait.h vx-share/xdr_ld.h \
+       vx-share/xdr_ptrace.h vx-share/xdr_rdb.h gdbthread.h \
+       dcache.h remote-utils.h top.h somsolib.h
+
+# Header files that already have srcdir in them, or which are in objdir.
+
+HFILES_WITH_SRCDIR = ../bfd/bfd.h
+
+
+# GDB "info" files, which should be included in their entirety
+INFOFILES = gdb.info*
+
+REMOTE_EXAMPLES = m68k-stub.c i386-stub.c sparc-stub.c rem-multi.shar
+
+# {X,T,NAT}DEPFILES are something of a pain in that it's hard to
+# default their values the way we do for SER_HARDWIRE; in the future
+# maybe much of the stuff now in {X,T,NAT}DEPFILES will go into other
+# variables analogous to SER_HARDWIRE which get defaulted in this
+# Makefile.in
+
+DEPFILES = $(TDEPFILES) $(SER_HARDWIRE) $(NATDEPFILES) \
+          $(REMOTE_OBS) $(SIM_OBS) $(CONFIG_LIB_OBS)
+
+SOURCES = $(SFILES) $(ALLDEPFILES) $(YYFILES) $(CONFIG_SRCS)
+# Don't include YYFILES (*.tab.c) because we already include *.y in SFILES,
+# and it's more useful to see it in the .y file.
+TAGFILES_NO_SRCDIR = $(SFILES) $(HFILES_NO_SRCDIR) $(ALLDEPFILES) \
+       $(SUBDIR_CLI_SRCS)
+TAGFILES_WITH_SRCDIR = $(HFILES_WITH_SRCDIR)
+
+COMMON_OBS = version.o blockframe.o breakpoint.o findvar.o regcache.o \
+       charset.o \
+       source.o values.o eval.o valops.o valarith.o valprint.o printcmd.o \
+       symtab.o symfile.o symmisc.o linespec.o infcmd.o infrun.o \
+       expprint.o environ.o stack.o thread.o \
+       macrotab.o macrocmd.o macroexp.o macroscope.o \
+       event-loop.o event-top.o inf-loop.o completer.o \
+       gdbarch.o arch-utils.o gdbtypes.o osabi.o copying.o $(DEPFILES) \
+       memattr.o mem-break.o target.o parse.o language.o $(YYOBJ) buildsym.o \
+       builtin-regs.o std-regs.o \
+       signals.o \
+       kod.o kod-cisco.o \
+       gdb-events.o \
+       exec.o bcache.o objfiles.o minsyms.o maint.o demangle.o \
+       dbxread.o coffread.o elfread.o \
+       dwarfread.o dwarf2read.o mipsread.o stabsread.o corefile.o \
+       c-lang.o f-lang.o \
+       ui-out.o cli-out.o \
+       varobj.o wrapper.o \
+       jv-lang.o jv-valprint.o jv-typeprint.o \
+       m2-lang.o p-lang.o p-typeprint.o p-valprint.o \
+       scm-exp.o scm-lang.o scm-valprint.o complaints.o typeprint.o \
+       c-typeprint.o f-typeprint.o m2-typeprint.o \
+       c-valprint.o cp-valprint.o f-valprint.o m2-valprint.o \
+       nlmread.o serial.o mdebugread.o top.o utils.o \
+       ui-file.o \
+       frame.o doublest.o \
+       gnu-v2-abi.o gnu-v3-abi.o hpacc-abi.o cp-abi.o cp-support.o
+
+OBS = $(COMMON_OBS) $(ANNOTATE_OBS)
+
+TSOBS = inflow.o
+
+SUBDIRS = @SUBDIRS@
+
+# For now, shortcut the "configure GDB for fewer languages" stuff.
+YYFILES = c-exp.tab.c \
+       ada-exp.tab.c \
+       jv-exp.tab.c \
+       f-exp.tab.c m2-exp.tab.c p-exp.tab.c
+YYOBJ = c-exp.tab.o \
+       jv-exp.tab.o \
+       f-exp.tab.o m2-exp.tab.o p-exp.tab.o
+
+# Things which need to be built when making a distribution.
+
+DISTSTUFF = $(YYFILES)
+
+# Prevent Sun make from putting in the machine type.  Setting
+# TARGET_ARCH to nothing works for SunOS 3, 4.0, but not for 4.1.
+.c.o:
+       $(CC) -c $(INTERNAL_CFLAGS) $<
+
+all: gdb$(EXEEXT) $(CONFIG_ALL)
+       @$(MAKE) $(FLAGS_TO_PASS) DO=all "DODIRS=`echo $(SUBDIRS) | sed 's/testsuite//'`" subdir_do
+
+installcheck:
+
+# The check target can not use subdir_do, because subdir_do does not
+# use TARGET_FLAGS_TO_PASS.
+check: force
+       @if [ -f testsuite/Makefile ]; then \
+         rootme=`pwd`; export rootme; \
+         rootsrc=`cd $(srcdir); pwd`; export rootsrc; \
+         cd testsuite; \
+         $(MAKE) $(TARGET_FLAGS_TO_PASS) check; \
+       else true; fi
+
+info dvi install-info clean-info html install-html: force
+       @$(MAKE) $(FLAGS_TO_PASS) DO=$@ "DODIRS=$(SUBDIRS)" subdir_do
+
+gdb.z:gdb.1
+       nroff -man $(srcdir)/gdb.1 | col -b > gdb.t 
+       pack gdb.t ; rm -f gdb.t
+       mv gdb.t.z gdb.z
+
+# Traditionally "install" depends on "all".  But it may be useful
+# not to; for example, if the user has made some trivial change to a 
+# source file and doesn't care about rebuilding or just wants to save the
+# time it takes for make to check that all is up to date.
+# install-only is intended to address that need.
+install: all install-only
+install-only: $(CONFIG_INSTALL)
+       transformed_name=`t='$(program_transform_name)'; \
+                         echo gdb | sed -e $$t` ; \
+               if test "x$$transformed_name" = x; then \
+                 transformed_name=gdb ; \
+               else \
+                 true ; \
+               fi ; \
+               $(srcdir)/../mkinstalldirs $(bindir) ; \
+               $(INSTALL_PROGRAM) gdb$(EXEEXT) $(bindir)/$$transformed_name$(EXEEXT) ; \
+               $(srcdir)/../mkinstalldirs $(man1dir) ; \
+               $(INSTALL_DATA) $(srcdir)/gdb.1 $(man1dir)/$$transformed_name.1
+       @$(MAKE) DO=install "DODIRS=$(SUBDIRS)" $(FLAGS_TO_PASS) subdir_do 
+
+uninstall: force $(CONFIG_UNINSTALL)
+       transformed_name=`t='$(program_transform_name)'; \
+                         echo gdb | sed -e $$t` ; \
+               if test "x$$transformed_name" = x; then \
+                 transformed_name=gdb ; \
+               else \
+                 true ; \
+               fi ; \
+               rm -f $(bindir)/$$transformed_name$(EXEEXT) $(man1dir)/$$transformed_name.1
+       rm -rf $(GDBTK_LIBRARY)
+       @$(MAKE) DO=uninstall "DODIRS=$(SUBDIRS)" $(FLAGS_TO_PASS) subdir_do 
+
+install-gdbtk:
+       $(SHELL) $(srcdir)/../mkinstalldirs $(GDBTK_LIBRARY) ; \
+       $(SHELL) $(srcdir)/../mkinstalldirs $(libdir)/insight$(GDBTK_VERSION) ; \
+       $(INSTALL_DATA) $(srcdir)/gdbtk/plugins/plugins.tcl $(libdir)/insight$(GDBTK_VERSION)/plugins.tcl ; \
+       $(SHELL) $(srcdir)/../mkinstalldirs \
+               $(GDBTK_LIBRARY)/images \
+               $(GDBTK_LIBRARY)/images2 ; \
+       $(SHELL) $(srcdir)/../mkinstalldirs $(GDBTK_LIBRARY)/help \
+               $(GDBTK_LIBRARY)/help/images \
+               $(GDBTK_LIBRARY)/help/trace ; \
+       cd $(srcdir)/gdbtk/library ; \
+       for i in *.tcl *.itcl *.ith *.itb images/*.gif images2/*.gif images/icons.txt images2/icons.txt tclIndex help/*.html  help/trace/*.html help/trace/index.toc help/images/*.gif; \
+         do \
+               $(INSTALL_DATA) $$i $(GDBTK_LIBRARY)/$$i ; \
+         done ;
+
+# We do this by grepping through sources.  If that turns out to be too slow,
+# maybe we could just require every .o file to have an initialization routine
+# of a given name (top.o -> _initialize_top, etc.).
+#
+# Formatting conventions:  The name of the _initialize_* routines must start
+# in column zero, and must not be inside #if.
+#
+# Note that the set of files with init functions might change, or the names
+# of the functions might change, so this files needs to depend on all the
+# object files that will be linked into gdb.
+#
+# FIXME: There are 2 problems with this approach. First, if the INIT_FILES
+# list includes a file twice (because of some mistake somewhere else) 
+# the _initialize_* function will be included twice in init.c. Second, 
+# init.c may force unnecessary files to be linked in.
+
+# FIXME: cagney/2002-06-09: gdb/564: gdb/563: Force the order so that
+# the first call is to _initialize_gdbtypes.  This is a hack to ensure
+# that all the architecture dependant global builtin_type_* variables
+# are initialized before anything else (per-architecture code is
+# called in the same order that it is registered).  The ``correct
+# fix'' is to have all the builtin types made part of the architecture
+# and initialize them on-demand (using gdbarch_data) just like
+# everything else.  The catch is that other modules still take the
+# address of these builtin types forcing them to be variables, sigh!
+
+INIT_FILES = $(OBS) $(TSOBS) $(CONFIG_OBS) $(CONFIG_INITS)
+init.c: $(INIT_FILES)
+       @echo Making init.c
+       @rm -f init.c-tmp init.l-tmp
+       @-echo $(INIT_FILES) | \
+       tr ' ' '\012' | \
+       sed -e '/^Onindy.o/d' \
+           -e '/^init.o/d' \
+           -e '/^nindy.o/d' \
+           -e '/ttyflush.o/d' \
+           -e '/xdr_ld.o/d' \
+           -e '/xdr_ptrace.o/d' \
+           -e '/xdr_rdb.o/d' \
+           -e '/udr.o/d' \
+           -e '/udip2soc.o/d' \
+           -e '/udi2go32.o/d' \
+           -e '/version.o/d' \
+           -e '/^[a-z0-9A-Z_]*_[SU].o/d' \
+           -e '/[a-z0-9A-Z_]*-exp.tab.o/d' \
+           -e 's/\.o/.c/' \
+           -e 's,signals\.c,signals/signals\.c,' \
+           -e 's|\([^  ][^     ]*\)|$(srcdir)/\1|g' | \
+       while read f; do grep '^_initialize_[a-z_0-9A-Z]* *(' $$f 2>/dev/null; done | \
+       sed -e 's/^.*://' -e 's/^\([a-z_0-9A-Z]*\).*/\1/' | \
+       ( echo _initialize_gdbtypes ; grep -v '^_initialize_gdbtypes$$' ) > init.l-tmp
+       @echo '/* Do not modify this file.  */' >>init.c-tmp
+       @echo '/* It is created automatically by the Makefile.  */'>>init.c-tmp
+       @echo '#include "defs.h"' >>init.c-tmp
+       @echo '#include "call-cmds.h"' >>init.c-tmp
+       @sed -e 's/\(.*\)/extern initialize_file_ftype \1;/' <init.l-tmp >>init.c-tmp
+       @echo 'void' >>init.c-tmp
+       @echo 'initialize_all_files (void)' >>init.c-tmp
+       @echo '{' >>init.c-tmp
+       @sed -e 's/\(.*\)/  \1 ();/' <init.l-tmp >>init.c-tmp
+       @echo '}' >>init.c-tmp
+       @rm init.l-tmp
+       @mv init.c-tmp init.c
+
+.PRECIOUS: init.c
+
+init.o: init.c $(defs_h) $(call_cmds_h)
+
+# Removing the old gdb first works better if it is running, at least on SunOS.
+gdb$(EXEEXT): main.o libgdb.a $(CONFIG_OBS) $(ADD_DEPS) $(CDEPS) $(TDEPLIBS)
+       rm -f gdb$(EXEEXT)
+       $(HLDENV) $(CC_LD) $(INTERNAL_LDFLAGS) $(WIN32LDAPP) -o gdb$(EXEEXT) \
+       main.o libgdb.a $(CONFIG_OBS) $(TDEPLIBS) $(TUI_LIBRARY) $(CLIBS)\
+       $(LOADLIBES)
+
+nlm:   force
+       rootme=`pwd`; export rootme; $(MAKE) $(TARGET_FLAGS_TO_PASS) DO=all DODIRS=nlm subdir_do
+
+# Create a library of the gdb object files and build GDB by linking
+# against that.
+#
+# init.o is very important.  It pulls in the rest of GDB.
+LIBGDB_OBS= $(OBS) $(TSOBS) $(ADD_FILES) init.o
+libgdb.a: $(LIBGDB_OBS)
+       -rm -f libgdb.a
+       $(AR) q libgdb.a $(LIBGDB_OBS)
+       $(RANLIB) libgdb.a
+
+saber_gdb: $(SFILES) $(DEPFILES) copying.c version.c
+       #setopt load_flags $(CFLAGS) $(BFD_CFLAGS) -DHOST_SYS=SUN4_SYS
+       #load ./init.c $(SFILES)
+       #unload $(srcdir)/c-exp.y
+       #unload $(srcdir)/jv-exp.y
+       #unload $(srcdir)/m2-exp.y
+       #unload $(srcdir)/p-exp.y
+       #unload vx-share/*.h
+       #unload nindy-share/[A-Z]*
+       #load c-exp.tab.c
+       #load jv-exp.tab.c
+       #load m2-exp.tab.c
+       #load p-exp.tab.c
+       #load copying.c version.c
+       #load ../opcodes/libopcodes.a
+       #load ../libiberty/libiberty.a
+       #load ../bfd/libbfd.a
+       #load ../readline/libreadline.a
+       #load ../mmalloc/libmmalloc.a
+       #load ../intl/libintl.a
+       #load -ltermcap 
+       #load `echo " "$(DEPFILES) | sed -e 's/\.o/.c/g' -e 's, , ../,g'`
+       echo "Load .c corresponding to:" $(DEPFILES)
+
+
+# A Mach 3.0 program to force gdb back to command level
+
+stop-gdb: stop-gdb.o
+       ${CC_LD} $(GLOBAL_CFLAGS) $(LDFLAGS) -o stop-gdb \
+       stop-gdb.o $(CLIBS) $(LOADLIBES)
+
+# This is useful when debugging GDB, because some Unix's don't let you run GDB
+# on itself without copying the executable.  So "make gdb1" will make
+# gdb and put a copy in gdb1, and you can run it with "gdb gdb1".
+# Removing gdb1 before the copy is the right thing if gdb1 is open
+# in another process.
+gdb1$(EXEEXT): gdb$(EXEEXT)
+       rm -f gdb1$(EXEEXT)
+       cp gdb$(EXEEXT) gdb1$(EXEEXT)
+
+# FIXME. These are not generated by "make depend" because they only are there
+# for some machines.
+# But these rules don't do what we want; we want to hack the foo.o: tm.h
+# dependency to do the right thing.
+tm-sun3.h tm-hp300bsd.h tm-altos.h: tm-m68k.h
+tm-hp300hpux.h tm-sun2.h tm-3b1.h: tm-m68k.h
+xm-i386-sv32.h: xm-i386.h
+tm-i386gas.h: tm-i386.h
+tm-sun4os4.h: tm-sparc.h
+xm-vaxult.h: xm-vax.h
+xm-vaxbsd.h: xm-vax.h
+
+# Put the proper machine-specific files first, so M-. on a machine
+# specific routine gets the one for the correct machine.  (FIXME: those
+# files go in twice; we should be removing them from the main list).
+
+# TAGS depends on all the files that go into it so you can rebuild TAGS
+# with `make TAGS' and not have to say `rm TAGS' first.
+
+TAGS: $(TAGFILES_NO_SRCDIR) $(TAGFILES_WITH_SRCDIR)
+       @echo Making TAGS
+       @etags $(srcdir)/$(TM_FILE) \
+         $(srcdir)/$(XM_FILE) \
+         $(srcdir)/$(NAT_FILE) \
+       `(for i in $(DEPFILES) $(TAGFILES_NO_SRCDIR); do \
+               echo $(srcdir)/$$i ; \
+       done ; for i in $(TAGFILES_WITH_SRCDIR); do \
+               echo $$i ; \
+       done) | sed -e 's/\.o$$/\.c/'` \
+       `find $(srcdir)/config -name '*.h' -print`
+
+tags: TAGS
+
+clean mostlyclean: $(CONFIG_CLEAN)
+       @$(MAKE) $(FLAGS_TO_PASS) DO=clean "DODIRS=$(SUBDIRS)" subdir_do 
+       rm -f *.o *.a $(ADD_FILES) *~ init.c-tmp init.l-tmp version.c-tmp
+       rm -f init.c version.c
+       rm -f gdb$(EXEEXT) core make.log
+       rm -f gdb[0-9]$(EXEEXT)
+
+# This used to depend on c-exp.tab.c m2-exp.tab.c TAGS
+# I believe this is wrong; the makefile standards for distclean just
+# describe removing files; the only sort of "re-create a distribution"
+# functionality described is if the distributed files are unmodified.
+# NB: While GDBSERVER might be configured on native systems, it isn't
+# always included in SUBDIRS.  Remove the gdbserver files explictly.
+distclean: clean
+       @$(MAKE) $(FLAGS_TO_PASS) DO=distclean "DODIRS=$(SUBDIRS)" subdir_do 
+       rm -f gdbserver/config.status gdbserver/config.log
+       rm -f gdbserver/tm.h gdbserver/xm.h gdbserver/nm.h
+       rm -f gdbserver/Makefile gdbserver/config.cache
+       rm -f nm.h tm.h xm.h config.status config.h stamp-h .gdbinit
+       rm -f y.output yacc.acts yacc.tmp y.tab.h
+       rm -f config.log config.cache
+       rm -f Makefile
+
+maintainer-clean: local-maintainer-clean do-maintainer-clean distclean
+realclean: maintainer-clean
+
+local-maintainer-clean:
+       @echo "This command is intended for maintainers to use;"
+       @echo "it deletes files that may require special tools to rebuild."
+       rm -f c-exp.tab.c \
+               ada-lex.c ada-exp.tab.c \
+               jv-exp.tab \
+               f-exp.tab.c m2-exp.tab.c p-exp.tab.c
+       rm -f TAGS $(INFOFILES)
+       rm -f $(YYFILES)
+       rm -f nm.h tm.h xm.h config.status
+
+do-maintainer-clean:
+       @$(MAKE) $(FLAGS_TO_PASS) DO=maintainer-clean "DODIRS=$(SUBDIRS)" \
+               subdir_do
+
+diststuff: $(DISTSTUFF)
+       cd doc; $(MAKE) $(MFLAGS) diststuff
+
+subdir_do: force
+       @for i in $(DODIRS); do \
+               if [ -f ./$$i/Makefile ] ; then \
+                       if (cd ./$$i; \
+                               $(MAKE) $(FLAGS_TO_PASS) $(DO)) ; then true ; \
+                       else exit 1 ; fi ; \
+               else true ; fi ; \
+       done
+
+Makefile: Makefile.in config.status @frags@
+       $(SHELL) config.status
+
+config.h: stamp-h ; @true
+stamp-h: config.in config.status
+       CONFIG_HEADERS=config.h:config.in $(SHELL) config.status
+
+config.status: configure
+       $(SHELL) config.status --recheck
+
+force:
+
+# Documentation!
+# GDB QUICK REFERENCE (TeX dvi file, CM fonts)
+doc/refcard.dvi:
+       cd doc; $(MAKE) refcard.dvi $(FLAGS_TO_PASS)
+
+# GDB QUICK REFERENCE (PostScript output, common PS fonts)
+doc/refcard.ps:
+       cd doc; $(MAKE) refcard.ps $(FLAGS_TO_PASS)
+
+# GDB MANUAL: TeX dvi file
+doc/gdb.dvi:
+       cd doc; $(MAKE) gdb.dvi $(FLAGS_TO_PASS)
+
+# GDB MANUAL: info file
+doc/gdb.info:
+       cd doc; $(MAKE) gdb.info $(FLAGS_TO_PASS)
+
+# Make copying.c from COPYING
+$(srcdir)/copying.c: @MAINTAINER_MODE_TRUE@ \
+               $(srcdir)/COPYING $(srcdir)/copying.awk
+       awk -f $(srcdir)/copying.awk \
+               < $(srcdir)/COPYING > $(srcdir)/copying.tmp
+       mv $(srcdir)/copying.tmp $(srcdir)/copying.c
+
+version.c: Makefile version.in
+       rm -f version.c-tmp version.c
+       echo '#include "version.h"' >> version.c-tmp
+       echo 'const char version[] = "'"`sed q ${srcdir}/version.in`"'";' >> version.c-tmp
+       echo 'const char host_name[] = "$(host_alias)";' >> version.c-tmp
+       echo 'const char target_name[] = "$(target_alias)";' >> version.c-tmp
+       mv version.c-tmp version.c
+version.o: version.c $(version_h)
+
+
+# LANG-exp.tab.c is generated in objdir from LANG-exp.y if it doesn't
+# exist in srcdir, then compiled in objdir to LANG-exp.tab.o.
+
+# If we said LANG-exp.tab.c rather than ./c-exp.tab.c some makes would
+# sometimes re-write it into $(srcdir)/c-exp.tab.c.
+
+# Remove bogus decls for malloc/realloc/free which conflict with
+# everything else.  Strictly speaking c-exp.tab.c should therefore
+# depend on Makefile.in, but that was a pretty big annoyance.
+
+# See comments above ...
+.PRECIOUS: c-exp.tab.c
+c-exp.tab.o: c-exp.tab.c
+c-exp.tab.c: c-exp.y
+       $(SHELL) $(YLWRAP) "$(YACC)" $(srcdir)/c-exp.y  y.tab.c c-exp.tmp -- $(YFLAGS) 
+       -sed -e '/extern.*malloc/d' \
+            -e '/extern.*realloc/d' \
+            -e '/extern.*free/d' \
+            -e '/include.*malloc.h/d' \
+            -e 's/malloc/xmalloc/g' \
+            -e 's/realloc/xrealloc/g' \
+            -e '/^#line.*y.tab.c/d' \
+         < c-exp.tmp > c-exp.new
+       -rm c-exp.tmp
+       mv c-exp.new ./c-exp.tab.c
+
+# See comments above ...
+.PRECIOUS: jv-exp.tab.c
+jv-exp.tab.o: jv-exp.tab.c
+jv-exp.tab.c: jv-exp.y
+       $(SHELL) $(YLWRAP) "$(YACC)" $(srcdir)/jv-exp.y  y.tab.c jv-exp.tmp -- $(YFLAGS) 
+       -sed -e '/extern.*malloc/d' \
+            -e '/extern.*realloc/d' \
+            -e '/extern.*free/d' \
+            -e '/include.*malloc.h/d' \
+            -e 's/malloc/xmalloc/g' \
+            -e 's/realloc/xrealloc/g' \
+            -e '/^#line.*y.tab.c/d' \
+         < jv-exp.tmp > jv-exp.new
+       -rm jv-exp.tmp
+       mv jv-exp.new ./jv-exp.tab.c
+
+# See comments above ...
+.PRECIOUS: f-exp.tab.c
+f-exp.tab.o: f-exp.tab.c
+f-exp.tab.c: f-exp.y c-exp.tab.c
+       $(SHELL) $(YLWRAP) "$(YACC)" $(srcdir)/f-exp.y  y.tab.c f-exp.tmp -- $(YFLAGS) 
+       -sed -e '/extern.*malloc/d' \
+            -e '/extern.*realloc/d' \
+            -e '/extern.*free/d' \
+            -e '/include.*malloc.h/d' \
+            -e 's/malloc/xmalloc/g' \
+            -e 's/realloc/xrealloc/g' \
+            -e '/^#line.*y.tab.c/d' \
+         < f-exp.tmp > f-exp.new
+       -rm f-exp.tmp
+       mv f-exp.new ./f-exp.tab.c
+
+# See comments above ...
+.PRECIOUS: m2-exp.tab.c
+m2-exp.tab.o: m2-exp.tab.c
+m2-exp.tab.c: m2-exp.y
+       $(SHELL) $(YLWRAP) "$(YACC)" $(srcdir)/m2-exp.y  y.tab.c m2-exp.tmp -- $(YFLAGS) 
+       -sed -e '/extern.*malloc/d' \
+            -e '/extern.*realloc/d' \
+            -e '/extern.*free/d' \
+            -e '/include.*malloc.h/d' \
+            -e 's/malloc/xmalloc/g' \
+            -e 's/realloc/xrealloc/g' \
+            -e '/^#line.*y.tab.c/d' \
+         < m2-exp.tmp > m2-exp.new
+       -rm m2-exp.tmp
+       mv m2-exp.new ./m2-exp.tab.c
+
+# See comments above ...
+.PRECIOUS: ada-exp.tab.c
+ada-exp.tab.o: ada-exp.tab.c
+ada-exp.tab.c: ada-exp.y 
+       $(YACC) $(YFLAGS) $(srcdir)/ada-exp.y
+       -sed -e '/extern.*malloc/d' \
+       -e '/extern.*realloc/d' \
+       -e '/extern.*free/d' \
+       -e '/include.*malloc.h/d' \
+       -e 's/malloc/xmalloc/g' \
+       -e 's/realloc/xrealloc/g' \
+       < y.tab.c > ada-exp.new
+       -rm y.tab.c
+       mv ada-exp.new ./ada-exp.tab.c
+
+# See comments above ...
+.PRECIOUS: ada-lex.c
+ada-lex.o: ada-lex.c
+ada-lex.c: ada-lex.l
+       @if [ "$(FLEX)" ] && $(FLEX) --version >/dev/null 2>&1; then \
+           echo $(FLEX) -Isit $(srcdir)/ada-lex.l ">" ada-lex.c; \
+           $(FLEX) -Isit $(srcdir)/ada-lex.l > ada-lex.c; \
+       elif [ ! -f ada-lex.c -a ! -f $(srcdir)/ada-lex.c ]; then \
+           echo "ada-lex.c missing and flex not available."; \
+           false; \
+       elif [ ! -f ada-lex.c ]; then \
+           echo "Warning: ada-lex.c older than ada-lex.l and flex not available."; \
+       fi
+
+# See comments above ...
+.PRECIOUS: p-exp.tab.c
+p-exp.tab.o: p-exp.tab.c
+p-exp.tab.c: p-exp.y
+       $(SHELL) $(YLWRAP) "$(YACC)" $(srcdir)/p-exp.y  y.tab.c p-exp.tmp -- $(YFLAGS)
+       -sed -e '/extern.*malloc/d' \
+            -e '/extern.*realloc/d' \
+            -e '/extern.*free/d' \
+            -e '/include.*malloc.h/d' \
+            -e 's/malloc/xmalloc/g' \
+            -e 's/realloc/xrealloc/g' \
+            -e '/^#line.*y.tab.c/d' \
+         < p-exp.tmp > p-exp.new
+       -rm p-exp.tmp
+       mv p-exp.new ./p-exp.tab.c
+
+lint: $(LINTFILES)
+       $(LINT) $(INCLUDE_CFLAGS) $(LINTFLAGS) $(LINTFILES) \
+          `echo $(DEPFILES) | sed 's/\.o /\.c /g'`
+
+gdb.cxref: $(SFILES)
+       cxref -I. $(SFILES) >gdb.cxref
+
+force_update:
+
+# GNU Make has an annoying habit of putting *all* the Makefile variables
+# into the environment, unless you include this target as a circumvention.
+# Rumor is that this will be fixed (and this target can be removed)
+# in GNU Make 4.0.
+.NOEXPORT:
+
+# GNU Make 3.63 has a different problem: it keeps tacking command line
+# overrides onto the definition of $(MAKE).  This variable setting
+# will remove them.
+MAKEOVERRIDES=
+
+## This is ugly, but I don't want GNU make to put these variables in
+## the environment.  Older makes will see this as a set of targets
+## with no dependencies and no actions.
+# OBSOLETE unexport CHILLFLAGS CHILL_LIB CHILL_FOR_TARGET :
+
+ALLDEPFILES = a68v-nat.c \
+       aix-thread.c \
+       alpha-nat.c alphabsd-nat.c \
+       alpha-tdep.c alpha-linux-tdep.c alphabsd-tdep.c alphanbsd-tdep.c \
+       alpha-osf1-tdep.c alphafbsd-tdep.c \
+       arm-linux-nat.c arm-linux-tdep.c arm-tdep.c \
+       armnbsd-nat.c armnbsd-tdep.c \
+       avr-tdep.c \
+       coff-solib.c \
+       core-sol2.c core-regset.c core-aout.c corelow.c \
+       dcache.c delta68-nat.c dpx2-nat.c exec.c fork-child.c \
+       go32-nat.c h8300-tdep.c h8500-tdep.c \
+       hp300ux-nat.c hppa-tdep.c hppab-nat.c hppah-nat.c hpread.c \
+       i386-tdep.c i386b-nat.c i386v-nat.c i386-linux-nat.c \
+       i386v4-nat.c i386ly-tdep.c \
+       i386bsd-nat.c i386bsd-tdep.c i386fbsd-nat.c \
+       i387-tdep.c \
+       i386-linux-tdep.c i386-nat.c \
+       i386gnu-nat.c i386gnu-tdep.c \
+       ia64-linux-nat.c ia64-linux-tdep.c ia64-tdep.c \
+       infptrace.c inftarg.c irix4-nat.c irix5-nat.c \
+       lynx-nat.c m3-nat.c \
+       m68hc11-tdep.c \
+       m68k-tdep.c \
+       mcore-tdep.c \
+       mips-linux-nat.c mips-linux-tdep.c \
+       mips-nat.c \
+       mips-irix-tdep.c \
+       mips-tdep.c mipsm3-nat.c mipsv4-nat.c \
+       mipsnbsd-nat.c mipsnbsd-tdep.c \
+       nbsd-tdep.c \
+       nindy-share/Onindy.c nindy-share/nindy.c \
+       nindy-share/ttyflush.c nindy-tdep.c \
+       ns32k-tdep.c solib-osf.c \
+       somread.c somsolib.c $(HPREAD_SOURCE) \
+       ppc-sysv-tdep.o ppc-linux-nat.c ppc-linux-tdep.c \
+       ppcnbsd-nat.o ppcnbsd-tdep.o \
+       procfs.c \
+       remote-array.c remote-e7000.c \
+       remote-es.c remote-hms.c remote-mips.c \
+       remote-rdp.c remote-sim.c \
+       remote-st.c remote-utils.c dcache.c \
+       remote-vx.c \
+       rs6000-nat.c rs6000-tdep.c \
+       s390-tdep.c s390-nat.c \
+       ser-go32.c ser-pipe.c ser-tcp.c \
+       sh-tdep.c shnbsd-tdep.c shnbsd-nat.c \
+       solib.c solib-irix.c solib-svr4.c solib-sunos.c sparc-linux-nat.c \
+       sparc-nat.c \
+       sparc64nbsd-nat.c sparcnbsd-nat.c sparcnbsd-tdep.c \
+       sparc-tdep.c sparcl-tdep.c sun3-nat.c \
+       symm-tdep.c symm-nat.c \
+       vax-tdep.c \
+       vx-share/xdr_ld.c vx-share/xdr_ptrace.c vx-share/xdr_rdb.c \
+       win32-nat.c \
+       xcoffread.c xcoffsolib.c \
+       xstormy16-tdep.c \
+       z8k-tdep.c
+
+# Some files need explict build rules (due to -Werror problems) or due
+# to sub-directory fun 'n' games.
+
+# Provide explicit rule/dependency - works for more makes.
+copying.o: $(srcdir)/copying.c
+       $(CC) -c $(INTERNAL_CFLAGS) $(srcdir)/copying.c
+
+hpux-thread.o: $(srcdir)/hpux-thread.c
+       $(CC) -c $(INTERNAL_CFLAGS) -I$(srcdir)/osf-share \
+               -I$(srcdir)/osf-share/HP800 -I/usr/include/dce \
+               $(srcdir)/hpux-thread.c
+
+# FIXME: Procfs.o gets -Wformat errors because things like pid_t don't
+# match output format strings.
+procfs.o: $(srcdir)/procfs.c
+       $(CC) -c $(INTERNAL_WARN_CFLAGS) $(NO_WERROR_CFLAGS) $(srcdir)/procfs.c
+
+v850ice.o: $(srcdir)/v850ice.c
+       $(CC) -c $(INTERNAL_CFLAGS) $(IDE_CFLAGS) $(ITCL_CFLAGS) \
+               $(TIX_CFLAGS) $(TCL_CFLAGS) $(TK_CFLAGS) $(X11_CFLAGS) \
+               $(GDBTK_CFLAGS) \
+               $(srcdir)/v850ice.c
+
+# FIXME: z8k-tdep.c calls _initialize_gdbtypes().  Since that isn't
+# declared -Wimplicit fails. It should be using the GDBARCH framework.
+# cagney 1999-09-02.
+z8k-tdep.o: $(srcdir)/z8k-tdep.c
+       $(CC) -c $(INTERNAL_WARN_CFLAGS) $(NO_WERROR_CFLAGS) \
+               $(srcdir)/z8k-tdep.c
+
+#
+# Generated YACC/LEX dependencies
+#
+
+c-exp.tab.o: c-exp.tab.c $(defs_h) $(gdb_string_h) $(expression_h) \
+       $(value_h) $(parser_defs_h) $(language_h) $(c_lang_h) $(bfd_h) \
+       $(charset_h) \
+       $(symfile_h) $(objfiles_h)
+
+jv-exp.tab.o: jv-exp.tab.c jv-lang.h $(defs_h) $(expression_h) \
+       $(gdbtypes_h) $(language_h) $(parser_defs_h) $(symtab_h) $(value_h) \
+       $(bfd_h) $(objfiles_h) $(symfile_h)
+
+f-exp.tab.o: f-exp.tab.c f-lang.h $(defs_h) $(expression_h) \
+       $(language_h) $(parser_defs_h) $(value_h) $(bfd_h) $(objfiles_h) \
+       $(symfile_h)
+
+m2-exp.tab.o: m2-exp.tab.c $(defs_h) $(expression_h) $(gdbtypes_h) \
+       $(language_h) m2-lang.h $(parser_defs_h) $(symtab_h) $(value_h) \
+       $(bfd_h) $(objfiles_h) $(symfile_h)
+
+p-exp.tab.o: p-exp.tab.c $(defs_h) $(expression_h) $(gdbtypes_h) \
+       $(language_h) p-lang.h $(parser_defs_h) $(symtab_h) $(value_h) \
+       $(bfd_h) $(objfiles_h) $(symfile_h)
+
+ada-exp.tab.o: ada-exp.tab.c ada-lex.c ada-lang.h \
+       $(defs_h) $(expression_h) \
+       $(gdbtypes_h) language.h parser-defs.h $(symtab_h) $(value_h) \
+       $(bfd_h) objfiles.h symfile.h
+
+#
+# The dependencies.  In aphabetic order.
+#
+
+a68v-nat.o: a68v-nat.c $(defs_h) $(inferior_h) $(regcache_h)
+abug-rom.o: abug-rom.c $(defs_h) $(gdbcore_h) $(target_h) $(monitor_h) \
+       $(serial_h) $(regcache_h)
+ada-lang.o: ada-lang.c $(gdb_string_h) $(demangle_h) $(defs_h) $(symtab_h) \
+       $(gdbtypes_h) $(gdbcmd_h) $(expression_h) $(parser_defs_h) \
+       $(language_h) $(c_lang_h) $(inferior_h) $(symfile_h) $(objfiles_h) \
+       $(breakpoint_h) $(gdbcore_h) $(ada_lang_h) $(ui_out_h)
+ada-tasks.o: ada-tasks.c $(defs_h) $(command_h) $(value_h) $(language_h) \
+       $(inferior_h) $(symtab_h) $(target_h) $(gdbcore_h) $(gregset_h) \
+       $(ada_lang_h)
+ada-typeprint.o: ada-typeprint.c $(defs_h) $(gdb_obstack_h) $(bfd_h) \
+       $(symtab_h) $(gdbtypes_h) $(expression_h) $(value_h) $(gdbcore_h) \
+       $(target_h) $(command_h) $(gdbcmd_h) $(language_h) $(demangle_h) \
+       $(c_lang_h) $(typeprint_h) $(ada_lang_h) $(gdb_string_h)
+ada-valprint.o: ada-valprint.c $(defs_h) $(symtab_h) $(gdbtypes_h) \
+       $(expression_h) $(value_h) $(demangle_h) $(valprint_h) $(language_h) \
+       $(annotate_h) $(ada_lang_h) $(c_lang_h)
+aix-thread.o: aix-thread.c $(defs_h) $(gdb_assert_h) $(gdbthread_h) \
+       $(target_h) $(inferior_h) $(regcache_h) $(gdbcmd_h) $(language_h) \
+       $(ppc_tdep_h)
+alpha-linux-tdep.o: alpha-linux-tdep.c $(defs_h) $(frame_h) $(gdbcore_h) \
+       $(value_h) $(alpha_tdep_h)
+alpha-nat.o: alpha-nat.c $(defs_h) $(inferior_h) $(gdbcore_h) $(target_h) \
+       $(regcache_h) $(alpha_tdep_h) $(gregset_h)
+alpha-osf1-tdep.o: alpha-osf1-tdep.c $(defs_h) $(frame_h) $(gdbcore_h) \
+       $(value_h) $(alpha_tdep_h)
+alpha-tdep.o: alpha-tdep.c $(defs_h) $(frame_h) $(inferior_h) $(symtab_h) \
+       $(value_h) $(gdbcmd_h) $(gdbcore_h) $(dis_asm_h) $(symfile_h) \
+       $(objfiles_h) $(gdb_string_h) $(linespec_h) $(regcache_h) \
+       $(doublest_h) $(arch_utils_h) $(elf_bfd_h) $(alpha_tdep_h)
+alphabsd-nat.o: alphabsd-nat.c $(defs_h) $(inferior_h) $(regcache_h) \
+       $(alpha_tdep_h) $(alphabsd_tdep_h) $(gregset_h)
+alphabsd-tdep.o: alphabsd-tdep.c $(defs_h) $(regcache_h) $(alpha_tdep_h) \
+       $(alphabsd_tdep_h)
+alphafbsd-tdep.o: alphafbsd-tdep.c $(defs_h) $(value_h) $(alpha_tdep_h)
+alphanbsd-tdep.o: alphanbsd-tdep.c $(defs_h) $(gdbcore_h) $(frame_h) \
+       $(regcache_h) $(value_h) $(solib_svr4_h) $(alpha_tdep_h) \
+       $(alphabsd_tdep_h) $(nbsd_tdep_h)
+annotate.o: annotate.c $(defs_h) $(annotate_h) $(value_h) $(target_h) \
+       $(gdbtypes_h) $(breakpoint_h)
+# OBSOLETE arc-tdep.o: arc-tdep.c
+arch-utils.o: arch-utils.c $(defs_h) $(arch_utils_h) $(gdbcmd_h) \
+       $(inferior_h) $(symtab_h) $(frame_h) $(inferior_h) $(breakpoint_h) \
+       $(gdb_wait_h) $(gdbcore_h) $(gdbcmd_h) $(target_h) $(annotate_h) \
+       $(gdb_string_h) $(regcache_h) $(gdb_assert_h) $(sim_regno_h) \
+       $(version_h) $(floatformat_h)
+arm-linux-nat.o: arm-linux-nat.c $(defs_h) $(inferior_h) $(gdbcore_h) \
+       $(gdb_string_h) $(regcache_h) $(arm_tdep_h) $(gregset_h)
+arm-linux-tdep.o: arm-linux-tdep.c $(defs_h) $(target_h) $(value_h) \
+       $(gdbtypes_h) $(floatformat_h) $(gdbcore_h) $(frame_h) $(regcache_h) \
+       $(doublest_h) $(arm_tdep_h) $(symtab_h) $(symfile_h) $(objfiles_h)
+arm-tdep.o: arm-tdep.c $(defs_h) $(frame_h) $(inferior_h) $(gdbcmd_h) \
+       $(gdbcore_h) $(symfile_h) $(gdb_string_h) $(dis_asm_h) $(regcache_h) \
+       $(doublest_h) $(value_h) $(arch_utils_h) $(solib_svr4_h) \
+       $(arm_tdep_h) $(gdb_sim_arm_h) $(elf_bfd_h) $(coff_internal_h) \
+       $(elf_arm_h) $(gdb_assert_h) $(bfd_in2_h) $(libcoff_h)
+armnbsd-nat.o: armnbsd-nat.c $(defs_h) $(arm_tdep_h) $(inferior_h) \
+       $(regcache_h) $(gdbcore_h)
+armnbsd-tdep.o: armnbsd-tdep.c $(defs_h) $(arm_tdep_h) $(nbsd_tdep_h) \
+       $(solib_svr4_h)
+avr-tdep.o: avr-tdep.c $(defs_h) $(gdbcmd_h) $(gdbcore_h) $(inferior_h) \
+       $(symfile_h) $(arch_utils_h) $(regcache_h) $(gdb_string_h)
+ax-gdb.o: ax-gdb.c $(defs_h) $(symtab_h) $(symfile_h) $(gdbtypes_h) \
+       $(value_h) $(expression_h) $(command_h) $(gdbcmd_h) $(frame_h) \
+       $(target_h) $(ax_h) $(ax_gdb_h) $(gdb_string_h)
+ax-general.o: ax-general.c $(defs_h) $(ax_h) $(value_h) $(gdb_string_h)
+bcache.o: bcache.c $(defs_h) $(gdb_obstack_h) $(bcache_h) $(gdb_string_h)
+blockframe.o: blockframe.c $(defs_h) $(symtab_h) $(bfd_h) $(symfile_h) \
+       $(objfiles_h) $(frame_h) $(gdbcore_h) $(value_h) $(target_h) \
+       $(inferior_h) $(annotate_h) $(regcache_h) $(gdb_assert_h)
+breakpoint.o: breakpoint.c $(defs_h) $(symtab_h) $(frame_h) $(breakpoint_h) \
+       $(gdbtypes_h) $(expression_h) $(gdbcore_h) $(gdbcmd_h) $(value_h) \
+       $(command_h) $(inferior_h) $(gdbthread_h) $(target_h) $(language_h) \
+       $(gdb_string_h) $(demangle_h) $(annotate_h) $(symfile_h) \
+       $(objfiles_h) $(linespec_h) $(completer_h) $(gdb_h) $(ui_out_h) \
+       $(cli_script_h) $(gdb_events_h) $(source_h)
+buildsym.o: buildsym.c $(defs_h) $(bfd_h) $(gdb_obstack_h) $(symtab_h) \
+       $(symfile_h) $(objfiles_h) $(gdbtypes_h) $(complaints_h) \
+       $(gdb_string_h) $(expression_h) $(language_h) $(bcache_h) \
+       $(filenames_h) $(macrotab_h) $(demangle_h) $(buildsym_h) \
+       $(stabsread_h)
+builtin-regs.o: builtin-regs.c $(defs_h) $(builtin_regs_h) $(gdbtypes_h) \
+       $(gdb_string_h) $(gdb_assert_h)
+c-lang.o: c-lang.c $(defs_h) $(symtab_h) $(gdbtypes_h) $(expression_h) \
+       $(parser_defs_h) $(language_h) $(c_lang_h) $(valprint_h) \
+       $(macroscope_h) $(gdb_assert_h)
+c-typeprint.o: c-typeprint.c $(defs_h) $(gdb_obstack_h) $(bfd_h) $(symtab_h) \
+       $(gdbtypes_h) $(expression_h) $(value_h) $(gdbcore_h) $(target_h) \
+       $(language_h) $(demangle_h) $(c_lang_h) $(typeprint_h) $(cp_abi_h) \
+       $(gdb_string_h)
+c-valprint.o: c-valprint.c $(defs_h) $(gdb_string_h) $(symtab_h) \
+       $(gdbtypes_h) $(expression_h) $(value_h) $(valprint_h) $(language_h) \
+       $(c_lang_h) $(cp_abi_h)
+# OBSOLETE ch-exp.o: ch-exp.c
+# OBSOLETE ch-lang.o: ch-lang.c
+# OBSOLETE ch-typeprint.o: ch-typeprint.c
+# OBSOLETE ch-valprint.o: ch-valprint.c
+cli-out.o: cli-out.c $(defs_h) $(ui_out_h) $(cli_out_h) $(gdb_string_h) \
+       $(gdb_assert_h)
+coff-solib.o: coff-solib.c $(defs_h) $(frame_h) $(bfd_h) $(gdbcore_h) \
+       $(symtab_h) $(symfile_h) $(objfiles_h)
+coffread.o: coffread.c $(defs_h) $(symtab_h) $(gdbtypes_h) $(demangle_h) \
+       $(breakpoint_h) $(bfd_h) $(gdb_obstack_h) $(gdb_string_h) \
+       $(coff_internal_h) $(libcoff_h) $(symfile_h) $(objfiles_h) \
+       $(buildsym_h) $(gdb_stabs_h) $(stabsread_h) $(complaints_h) \
+       $(target_h) $(gdb_assert_h)
+complaints.o: complaints.c $(defs_h) $(complaints_h) $(gdb_assert_h) \
+       $(command_h) $(gdbcmd_h)
+completer.o: completer.c $(defs_h) $(symtab_h) $(gdbtypes_h) $(expression_h) \
+       $(filenames_h) $(cli_decode_h) $(gdbcmd_h) $(completer_h)
+copying.o: copying.c $(defs_h) $(command_h) $(gdbcmd_h)
+core-aout.o: core-aout.c $(defs_h) $(gdbcore_h) $(value_h) $(regcache_h) \
+       $(gdb_dirent_h) $(gdb_stat_h)
+core-regset.o: core-regset.c $(defs_h) $(gdb_string_h) $(inferior_h) \
+       $(target_h) $(command_h) $(gdbcore_h) $(gregset_h)
+core-sol2.o: core-sol2.c $(defs_h) $(gdb_string_h) $(regcache_h) \
+       $(inferior_h) $(target_h) $(command_h) $(gdbcore_h) $(gregset_h)
+corefile.o: corefile.c $(defs_h) $(gdb_string_h) $(inferior_h) $(symtab_h) \
+       $(command_h) $(gdbcmd_h) $(bfd_h) $(target_h) $(gdbcore_h) \
+       $(dis_asm_h) $(gdb_stat_h) $(completer_h)
+corelow.o: corelow.c $(defs_h) $(gdb_string_h) $(frame_h) $(inferior_h) \
+       $(symtab_h) $(command_h) $(bfd_h) $(target_h) $(gdbcore_h) \
+       $(gdbthread_h) $(regcache_h) $(symfile_h)
+cp-abi.o: cp-abi.c $(defs_h) $(value_h) $(cp_abi_h) $(gdb_string_h)
+cp-support.o: cp-support.c $(defs_h) $(cp_support_h)
+cp-valprint.o: cp-valprint.c $(defs_h) $(gdb_obstack_h) $(symtab_h) \
+       $(gdbtypes_h) $(expression_h) $(value_h) $(command_h) $(gdbcmd_h) \
+       $(demangle_h) $(annotate_h) $(gdb_string_h) $(c_lang_h) $(target_h) \
+       $(cp_abi_h)
+cpu32bug-rom.o: cpu32bug-rom.c $(defs_h) $(gdbcore_h) $(target_h) \
+       $(monitor_h) $(serial_h) $(regcache_h)
+cris-tdep.o: cris-tdep.c $(defs_h) $(frame_h) $(symtab_h) $(inferior_h) \
+       $(gdbtypes_h) $(gdbcore_h) $(gdbcmd_h) $(target_h) $(value_h) \
+       $(opcode_cris_h) $(arch_utils_h) $(regcache_h) $(symfile_h) \
+       $(solib_h) $(solib_svr4_h)
+# OBSOLETE cxux-nat.o: cxux-nat.c
+d10v-tdep.o: d10v-tdep.c $(defs_h) $(frame_h) $(symtab_h) $(gdbtypes_h) \
+       $(gdbcmd_h) $(gdbcore_h) $(gdb_string_h) $(value_h) $(inferior_h) \
+       $(dis_asm_h) $(symfile_h) $(objfiles_h) $(language_h) \
+       $(arch_utils_h) $(regcache_h) $(floatformat_h) $(gdb_sim_d10v_h) \
+       $(sim_regno_h)
+# OBSOLETE d30v-tdep.o: d30v-tdep.c
+dbug-rom.o: dbug-rom.c $(defs_h) $(gdbcore_h) $(target_h) $(monitor_h) \
+       $(serial_h) $(regcache_h)
+dbxread.o: dbxread.c $(defs_h) $(gdb_string_h) $(gdb_obstack_h) \
+       $(gdb_stat_h) $(symtab_h) $(breakpoint_h) $(target_h) $(gdbcore_h) \
+       $(libaout_h) $(symfile_h) $(objfiles_h) $(buildsym_h) $(stabsread_h) \
+       $(gdb_stabs_h) $(demangle_h) $(language_h) $(complaints_h) \
+       $(cp_abi_h) $(aout_aout64_h) $(aout_stab_gnu_h)
+dcache.o: dcache.c $(defs_h) $(dcache_h) $(gdbcmd_h) $(gdb_string_h) \
+       $(gdbcore_h) $(target_h)
+delta68-nat.o: delta68-nat.c $(defs_h)
+demangle.o: demangle.c $(defs_h) $(command_h) $(gdbcmd_h) $(demangle_h) \
+       $(gdb_string_h)
+dink32-rom.o: dink32-rom.c $(defs_h) $(gdbcore_h) $(target_h) $(monitor_h) \
+       $(serial_h) $(symfile_h) $(inferior_h) $(regcache_h)
+doublest.o: doublest.c $(defs_h) $(doublest_h) $(floatformat_h) \
+       $(gdb_assert_h) $(gdb_string_h) $(gdbtypes_h)
+dpx2-nat.o: dpx2-nat.c $(defs_h) $(gdbcore_h) $(gdb_string_h)
+dsrec.o: dsrec.c $(defs_h) $(serial_h) $(srec_h)
+# OBSOLETE dstread.o: dstread.c
+dve3900-rom.o: dve3900-rom.c $(defs_h) $(gdbcore_h) $(target_h) $(monitor_h) \
+       $(serial_h) $(inferior_h) $(command_h) $(gdb_string_h) $(regcache_h)
+dwarf2cfi.o: dwarf2cfi.c $(defs_h) $(gdbcore_h) $(symtab_h) $(symfile_h) \
+       $(objfiles_h) $(target_h) $(elf_dwarf2_h) $(inferior_h) \
+       $(regcache_h) $(dwarf2cfi_h) $(gdb_assert_h)
+dwarf2read.o: dwarf2read.c $(defs_h) $(bfd_h) $(symtab_h) $(gdbtypes_h) \
+       $(symfile_h) $(objfiles_h) $(elf_dwarf2_h) $(buildsym_h) \
+       $(demangle_h) $(expression_h) $(filenames_h) $(macrotab_h) \
+       $(language_h) $(complaints_h) $(bcache_h) $(gdb_string_h) \
+       $(gdb_assert_h)
+dwarfread.o: dwarfread.c $(defs_h) $(symtab_h) $(gdbtypes_h) $(symfile_h) \
+       $(objfiles_h) $(elf_dwarf_h) $(buildsym_h) $(demangle_h) \
+       $(expression_h) $(language_h) $(complaints_h) $(gdb_string_h)
+elfread.o: elfread.c $(defs_h) $(bfd_h) $(gdb_string_h) $(elf_bfd_h) \
+       $(elf_mips_h) $(symtab_h) $(symfile_h) $(objfiles_h) $(buildsym_h) \
+       $(stabsread_h) $(gdb_stabs_h) $(complaints_h) $(demangle_h)
+environ.o: environ.c $(defs_h) $(environ_h) $(gdb_string_h)
+eval.o: eval.c $(defs_h) $(gdb_string_h) $(symtab_h) $(gdbtypes_h) \
+       $(value_h) $(expression_h) $(target_h) $(frame_h) $(language_h) \
+       $(f_lang_h) $(cp_abi_h)
+event-loop.o: event-loop.c $(defs_h) $(event_loop_h) $(event_top_h) \
+       $(gdb_string_h)
+event-top.o: event-top.c $(defs_h) $(top_h) $(inferior_h) $(target_h) \
+       $(terminal_h) $(event_loop_h) $(event_top_h) $(gdbcmd_h)
+exec.o: exec.c $(defs_h) $(frame_h) $(inferior_h) $(target_h) $(gdbcmd_h) \
+       $(language_h) $(symfile_h) $(objfiles_h) $(completer_h) $(value_h) \
+       $(gdb_string_h) $(gdbcore_h) $(gdb_stat_h) $(xcoffsolib_h)
+expprint.o: expprint.c $(defs_h) $(symtab_h) $(gdbtypes_h) $(expression_h) \
+       $(value_h) $(language_h) $(parser_defs_h)
+f-lang.o: f-lang.c $(defs_h) $(gdb_string_h) $(symtab_h) $(gdbtypes_h) \
+       $(expression_h) $(parser_defs_h) $(language_h) $(f_lang_h) \
+       $(valprint_h)
+f-typeprint.o: f-typeprint.c $(defs_h) $(gdb_obstack_h) $(bfd_h) $(symtab_h) \
+       $(gdbtypes_h) $(expression_h) $(value_h) $(gdbcore_h) $(target_h) \
+       $(f_lang_h) $(gdb_string_h)
+f-valprint.o: f-valprint.c $(defs_h) $(gdb_string_h) $(symtab_h) \
+       $(gdbtypes_h) $(expression_h) $(value_h) $(valprint_h) $(language_h) \
+       $(f_lang_h) $(frame_h) $(gdbcore_h) $(command_h)
+fbsd-proc.o: fbsd-proc.c $(defs_h) $(gdbcore_h) $(inferior_h) \
+       $(gdb_string_h) $(elf_bfd_h) $(gregset_h)
+findvar.o: findvar.c $(defs_h) $(symtab_h) $(gdbtypes_h) $(frame_h) \
+       $(value_h) $(gdbcore_h) $(inferior_h) $(target_h) $(gdb_string_h) \
+       $(gdb_assert_h) $(floatformat_h) $(symfile_h) $(regcache_h) \
+       $(builtin_regs_h)
+fork-child.o: fork-child.c $(defs_h) $(gdb_string_h) $(frame_h) \
+       $(inferior_h) $(target_h) $(gdb_wait_h) $(gdb_vfork_h) $(gdbcore_h) \
+       $(terminal_h) $(gdbthread_h) $(command_h)
+# OBSOLETE fr30-tdep.o: fr30-tdep.c
+frame.o: frame.c $(defs_h) $(frame_h) $(target_h) $(value_h) $(inferior_h) \
+       $(regcache_h) $(gdb_assert_h)
+frv-tdep.o: frv-tdep.c $(defs_h) $(inferior_h) $(symfile_h) $(gdbcore_h) \
+       $(arch_utils_h) $(regcache_h)
+gcore.o: gcore.c $(defs_h) $(cli_decode_h) $(inferior_h) $(gdbcore_h) \
+       $(elf_bfd_h) $(symfile_h) $(objfiles_h)
+gdb-events.o: gdb-events.c $(defs_h) $(gdb_events_h) $(gdbcmd_h)
+gdbarch.o: gdbarch.c $(defs_h) $(arch_utils_h) $(gdbcmd_h) $(inferior_h) \
+       $(gdb_string_h) $(symtab_h) $(frame_h) $(inferior_h) $(breakpoint_h) \
+       $(gdb_wait_h) $(gdbcore_h) $(gdbcmd_h) $(target_h) $(gdbthread_h) \
+       $(annotate_h) $(symfile_h) $(value_h) $(symcat_h) $(floatformat_h) \
+       $(gdb_assert_h) $(gdb_string_h) $(gdb_events_h)
+gdbtypes.o: gdbtypes.c $(defs_h) $(gdb_string_h) $(bfd_h) $(symtab_h) \
+       $(symfile_h) $(objfiles_h) $(gdbtypes_h) $(expression_h) \
+       $(language_h) $(target_h) $(value_h) $(demangle_h) $(complaints_h) \
+       $(gdbcmd_h) $(wrapper_h) $(cp_abi_h) $(gdb_assert_h)
+gnu-nat.o: gnu-nat.c $(gdb_string_h) $(defs_h) $(inferior_h) $(symtab_h) \
+       $(value_h) $(language_h) $(target_h) $(gdb_wait_h) $(gdbcmd_h) \
+       $(gdbcore_h) $(gdbthread_h) $(gdb_assert_h) $(gnu_nat_h) \
+       $(exc_request_S_h) $(notify_S_h) $(process_reply_S_h) \
+       $(msg_reply_S_h) $(exc_request_U_h) $(msg_U_h)
+gnu-v2-abi.o: gnu-v2-abi.c $(defs_h) $(gdb_string_h) $(symtab_h) \
+       $(gdbtypes_h) $(value_h) $(demangle_h) $(cp_abi_h)
+gnu-v3-abi.o: gnu-v3-abi.c $(defs_h) $(value_h) $(cp_abi_h) $(demangle_h) \
+       $(gdb_assert_h) $(gdb_string_h)
+go32-nat.o: go32-nat.c $(defs_h) $(inferior_h) $(gdb_wait_h) $(gdbcore_h) \
+       $(command_h) $(gdbcmd_h) $(floatformat_h) $(buildsym_h) \
+       $(i387_tdep_h) $(i386_tdep_h) $(value_h) $(regcache_h) \
+       $(gdb_string_h)
+h8300-tdep.o: h8300-tdep.c $(defs_h) $(frame_h) $(symtab_h) $(dis_asm_h) \
+       $(gdbcmd_h) $(gdbtypes_h) $(gdbcore_h) $(gdb_string_h) $(value_h) \
+       $(regcache_h)
+h8500-tdep.o: h8500-tdep.c $(defs_h) $(frame_h) $(symtab_h) $(gdbtypes_h) \
+       $(gdbcmd_h) $(value_h) $(dis_asm_h) $(gdbcore_h) $(regcache_h)
+hp300ux-nat.o: hp300ux-nat.c $(defs_h) $(frame_h) $(inferior_h) \
+       $(regcache_h)
+hpacc-abi.o: hpacc-abi.c $(defs_h) $(value_h) $(gdb_regex_h) $(gdb_string_h) \
+       $(gdbtypes_h) $(gdbcore_h) $(cp_abi_h)
+hppa-tdep.o: hppa-tdep.c $(defs_h) $(frame_h) $(bfd_h) $(inferior_h) \
+       $(value_h) $(regcache_h) $(completer_h) $(symtab_h) $(a_out_encap_h) \
+       $(gdb_stat_h) $(gdb_wait_h) $(gdbcore_h) $(gdbcmd_h) $(target_h) \
+       $(symfile_h) $(objfiles_h)
+hppab-nat.o: hppab-nat.c $(defs_h) $(inferior_h) $(target_h) $(regcache_h)
+hppah-nat.o: hppah-nat.c $(defs_h) $(inferior_h) $(target_h) $(gdbcore_h) \
+       $(gdb_wait_h) $(regcache_h)
+hppam3-nat.o: hppam3-nat.c $(defs_h) $(inferior_h) $(floatformat_h) \
+       $(regcache_h)
+hpread.o: hpread.c $(defs_h) $(bfd_h) $(gdb_string_h) $(hp_symtab_h) \
+       $(syms_h) $(symtab_h) $(symfile_h) $(objfiles_h) $(buildsym_h) \
+       $(complaints_h) $(gdb_stabs_h) $(gdbtypes_h) $(demangle_h) \
+       $(gdb_string_h)
+hpux-thread.o: hpux-thread.c $(defs_h) $(gdbthread_h) $(target_h) \
+       $(inferior_h) $(regcache_h) $(gdbcore_h)
+i386-linux-nat.o: i386-linux-nat.c $(defs_h) $(inferior_h) $(gdbcore_h) \
+       $(regcache_h) $(gdb_assert_h) $(gdb_string_h) $(gregset_h) \
+       $(i387_tdep_h) $(i386_tdep_h) $(i386_linux_tdep_h)
+i386-linux-tdep.o: i386-linux-tdep.c $(defs_h) $(gdbcore_h) $(frame_h) \
+       $(value_h) $(regcache_h) $(inferior_h) $(symtab_h) $(symfile_h) \
+       $(objfiles_h) $(solib_svr4_h) $(i386_tdep_h) $(i386_linux_tdep_h)
+i386-nat.o: i386-nat.c $(defs_h) $(breakpoint_h) $(command_h) $(gdbcmd_h)
+i386-sol2-tdep.o: i386-sol2-tdep.c $(defs_h) $(value_h) $(i386_tdep_h)
+i386-stub.o: i386-stub.c
+i386-tdep.o: i386-tdep.c $(defs_h) $(gdb_string_h) $(frame_h) $(inferior_h) \
+       $(gdbcore_h) $(objfiles_h) $(target_h) $(floatformat_h) $(symfile_h) \
+       $(symtab_h) $(gdbcmd_h) $(command_h) $(arch_utils_h) $(regcache_h) \
+       $(doublest_h) $(value_h) $(gdb_assert_h) $(i386_tdep_h) \
+       $(i387_tdep_h)
+# OBSOLETE i386aix-nat.o: i386aix-nat.c
+i386b-nat.o: i386b-nat.c $(defs_h)
+i386bsd-nat.o: i386bsd-nat.c $(defs_h) $(inferior_h) $(regcache_h) \
+       $(gdb_assert_h) $(gregset_h) $(i386_tdep_h) $(i387_tdep_h)
+i386bsd-tdep.o: i386bsd-tdep.c $(defs_h) $(arch_utils_h) $(frame_h) \
+       $(gdbcore_h) $(regcache_h) $(gdb_string_h) $(i386_tdep_h)
+i386fbsd-nat.o: i386fbsd-nat.c $(defs_h) $(inferior_h) $(regcache_h)
+i386gnu-nat.o: i386gnu-nat.c $(defs_h) $(inferior_h) $(floatformat_h) \
+       $(regcache_h) $(gdb_assert_h) $(i386_tdep_h) $(gnu_nat_h) \
+       $(i387_tdep_h)
+i386gnu-tdep.o: i386gnu-tdep.c $(defs_h) $(i386_tdep_h)
+i386ly-tdep.o: i386ly-tdep.c $(defs_h) $(gdbcore_h) $(inferior_h) \
+       $(regcache_h) $(target_h) $(i386_tdep_h)
+# OBSOLETE i386m3-nat.o: i386m3-nat.c
+# OBSOLETE i386mach-nat.o: i386mach-nat.c
+i386nbsd-tdep.o: i386nbsd-tdep.c $(defs_h) $(gdbtypes_h) $(gdbcore_h) \
+       $(regcache_h) $(arch_utils_h) $(i386_tdep_h) $(i387_tdep_h) \
+       $(nbsd_tdep_h) $(solib_svr4_h)
+i386obsd-nat.o: i386obsd-nat.c $(defs_h)
+i386v-nat.o: i386v-nat.c $(defs_h) $(frame_h) $(inferior_h) $(language_h) \
+       $(gdbcore_h) $(gdb_stat_h) $(floatformat_h) $(target_h)
+i386v4-nat.o: i386v4-nat.c $(defs_h) $(value_h) $(inferior_h) $(regcache_h) \
+       $(i386_tdep_h) $(i387_tdep_h) $(gregset_h)
+i387-tdep.o: i387-tdep.c $(defs_h) $(frame_h) $(inferior_h) $(language_h) \
+       $(value_h) $(gdbcore_h) $(floatformat_h) $(regcache_h) \
+       $(gdb_assert_h) $(gdb_string_h) $(doublest_h) $(i386_tdep_h)
+# OBSOLETE i960-tdep.o: i960-tdep.c
+ia64-aix-nat.o: ia64-aix-nat.c $(defs_h) $(inferior_h) $(target_h) \
+       $(gdbcore_h) $(regcache_h) $(symtab_h) $(bfd_h) $(symfile_h) \
+       $(objfiles_h) $(gdb_stat_h)
+ia64-aix-tdep.o: ia64-aix-tdep.c $(defs_h)
+ia64-linux-nat.o: ia64-linux-nat.c $(defs_h) $(inferior_h) $(target_h) \
+       $(gdbcore_h) $(regcache_h) $(gregset_h)
+ia64-linux-tdep.o: ia64-linux-tdep.c $(defs_h) $(arch_utils_h)
+ia64-tdep.o: ia64-tdep.c $(defs_h) $(inferior_h) $(symfile_h) $(gdbcore_h) \
+       $(arch_utils_h) $(floatformat_h) $(regcache_h) $(doublest_h) \
+       $(value_h) $(objfiles_h) $(elf_common_h) $(elf_bfd_h)
+inf-loop.o: inf-loop.c $(defs_h) $(inferior_h) $(target_h) $(event_loop_h) \
+       $(event_top_h) $(inf_loop_h) $(remote_h)
+infcmd.o: infcmd.c $(defs_h) $(gdb_string_h) $(symtab_h) $(gdbtypes_h) \
+       $(frame_h) $(inferior_h) $(environ_h) $(value_h) $(gdbcmd_h) \
+       $(symfile_h) $(gdbcore_h) $(target_h) $(language_h) $(symfile_h) \
+       $(objfiles_h) $(completer_h) $(ui_out_h) $(event_top_h) \
+       $(parser_defs_h) $(regcache_h)
+inflow.o: inflow.c $(defs_h) $(frame_h) $(inferior_h) $(command_h) \
+       $(serial_h) $(terminal_h) $(target_h) $(gdbthread_h) $(gdb_string_h)
+infptrace.o: infptrace.c $(defs_h) $(frame_h) $(inferior_h) $(target_h) \
+       $(gdb_string_h) $(regcache_h) $(gdb_wait_h) $(command_h) \
+       $(gdb_dirent_h) $(gdbcore_h) $(gdb_stat_h)
+infrun.o: infrun.c $(defs_h) $(gdb_string_h) $(symtab_h) $(frame_h) \
+       $(inferior_h) $(breakpoint_h) $(gdb_wait_h) $(gdbcore_h) $(gdbcmd_h) \
+       $(cli_script_h) $(target_h) $(gdbthread_h) $(annotate_h) \
+       $(symfile_h) $(top_h) $(inf_loop_h) $(regcache_h) $(value_h)
+inftarg.o: inftarg.c $(defs_h) $(frame_h) $(inferior_h) $(target_h) \
+       $(gdbcore_h) $(command_h) $(gdb_stat_h) $(gdb_wait_h)
+infttrace.o: infttrace.c $(defs_h) $(frame_h) $(inferior_h) $(target_h) \
+       $(gdb_string_h) $(gdb_wait_h) $(command_h) $(gdbcore_h)
+irix4-nat.o: irix4-nat.c $(defs_h) $(inferior_h) $(gdbcore_h) $(regcache_h) \
+       $(gregset_h)
+irix5-nat.o: irix5-nat.c $(defs_h) $(inferior_h) $(gdbcore_h) $(target_h) \
+       $(regcache_h) $(gdb_string_h) $(gregset_h)
+jv-lang.o: jv-lang.c $(defs_h) $(symtab_h) $(gdbtypes_h) $(expression_h) \
+       $(parser_defs_h) $(language_h) $(gdbtypes_h) $(symtab_h) \
+       $(symfile_h) $(objfiles_h) $(gdb_string_h) $(value_h) $(c_lang_h) \
+       $(jv_lang_h) $(gdbcore_h)
+jv-typeprint.o: jv-typeprint.c $(defs_h) $(symtab_h) $(gdbtypes_h) \
+       $(value_h) $(demangle_h) $(jv_lang_h) $(gdb_string_h) $(typeprint_h) \
+       $(c_lang_h) $(cp_abi_h)
+jv-valprint.o: jv-valprint.c $(defs_h) $(symtab_h) $(gdbtypes_h) \
+       $(gdbcore_h) $(expression_h) $(value_h) $(demangle_h) $(valprint_h) \
+       $(language_h) $(jv_lang_h) $(c_lang_h) $(annotate_h) $(gdb_string_h)
+kod-cisco.o: kod-cisco.c $(defs_h) $(gdb_string_h) $(kod_h)
+kod.o: kod.c $(defs_h) $(command_h) $(gdbcmd_h) $(target_h) $(gdb_string_h) \
+       $(kod_h)
+language.o: language.c $(defs_h) $(gdb_string_h) $(symtab_h) $(gdbtypes_h) \
+       $(value_h) $(gdbcmd_h) $(expression_h) $(language_h) $(target_h) \
+       $(parser_defs_h) $(jv_lang_h)
+lin-lwp.o: lin-lwp.c $(defs_h) $(gdb_assert_h) $(gdb_string_h) $(gdb_wait_h) \
+       $(gdbthread_h) $(inferior_h) $(target_h) $(regcache_h) $(gdbcmd_h)
+linespec.o: linespec.c $(defs_h) $(symtab_h) $(frame_h) $(command_h) \
+       $(symfile_h) $(objfiles_h) $(demangle_h) $(value_h) $(completer_h) \
+       $(cp_abi_h) $(source_h)
+linux-proc.o: linux-proc.c $(defs_h) $(inferior_h) $(regcache_h) \
+       $(gregset_h) $(gdbcore_h) $(gdbthread_h) $(elf_bfd_h) \
+       $(cli_decode_h) $(gdb_string_h)
+lynx-nat.o: lynx-nat.c $(defs_h) $(frame_h) $(inferior_h) $(target_h) \
+       $(gdbcore_h) $(regcache_h)
+m2-lang.o: m2-lang.c $(defs_h) $(symtab_h) $(gdbtypes_h) $(expression_h) \
+       $(parser_defs_h) $(language_h) $(m2_lang_h) $(c_lang_h) \
+       $(valprint_h)
+m2-typeprint.o: m2-typeprint.c $(defs_h) $(bfd_h) $(symtab_h) $(gdbtypes_h) \
+       $(expression_h) $(value_h) $(gdbcore_h) $(target_h) $(m2_lang_h)
+m2-valprint.o: m2-valprint.c $(defs_h) $(symtab_h) $(gdbtypes_h) \
+       $(m2_lang_h)
+m3-nat.o: m3-nat.c $(defs_h) $(inferior_h) $(symtab_h) $(value_h) \
+       $(language_h) $(target_h) $(gdb_wait_h) $(gdbcmd_h) $(gdbcore_h) \
+       $(regcache_h)
+m32r-rom.o: m32r-rom.c $(defs_h) $(gdbcore_h) $(target_h) $(monitor_h) \
+       $(serial_h) $(symtab_h) $(command_h) $(gdbcmd_h) $(symfile_h) \
+       $(gdb_string_h) $(objfiles_h) $(inferior_h) $(regcache_h)
+m32r-stub.o: m32r-stub.c $(syscall_h)
+m32r-tdep.o: m32r-tdep.c $(defs_h) $(frame_h) $(inferior_h) $(target_h) \
+       $(value_h) $(bfd_h) $(gdb_string_h) $(gdbcore_h) $(symfile_h) \
+       $(regcache_h)
+m68hc11-tdep.o: m68hc11-tdep.c $(defs_h) $(frame_h) $(symtab_h) \
+       $(gdbtypes_h) $(gdbcmd_h) $(gdbcore_h) $(gdb_string_h) $(value_h) \
+       $(inferior_h) $(dis_asm_h) $(symfile_h) $(objfiles_h) \
+       $(arch_utils_h) $(regcache_h) $(target_h) $(opcode_m68hc11_h) \
+       $(elf_m68hc11_h) $(elf_bfd_h)
+m68k-stub.o: m68k-stub.c
+m68k-tdep.o: m68k-tdep.c $(defs_h) $(frame_h) $(symtab_h) $(gdbcore_h) \
+       $(value_h) $(gdb_string_h) $(inferior_h) $(regcache_h) \
+       $(arch_utils_h) $(gregset_h)
+m68klinux-nat.o: m68klinux-nat.c $(defs_h) $(frame_h) $(inferior_h) \
+       $(language_h) $(gdbcore_h) $(regcache_h) $(gdb_stat_h) \
+       $(floatformat_h) $(target_h) $(gregset_h)
+m68knbsd-nat.o: m68knbsd-nat.c $(defs_h) $(inferior_h) $(gdbcore_h) \
+       $(regcache_h)
+m68knbsd-tdep.o: m68knbsd-tdep.c $(defs_h) $(gdbtypes_h) $(regcache_h)
+# OBSOLETE m88k-nat.o: m88k-nat.c
+# OBSOLETE m88k-tdep.o: m88k-tdep.c
+macrocmd.o: macrocmd.c $(defs_h) $(macrotab_h) $(macroexp_h) $(macroscope_h) \
+       $(command_h) $(gdbcmd_h)
+macroexp.o: macroexp.c $(defs_h) $(gdb_obstack_h) $(bcache_h) $(macrotab_h) \
+       $(macroexp_h) $(gdb_assert_h)
+macroscope.o: macroscope.c $(defs_h) $(macroscope_h) $(symtab_h) $(target_h) \
+       $(frame_h) $(inferior_h) $(source_h)
+macrotab.o: macrotab.c $(defs_h) $(gdb_obstack_h) $(splay_tree_h) \
+       $(symtab_h) $(symfile_h) $(objfiles_h) $(macrotab_h) $(gdb_assert_h) \
+       $(bcache_h) $(complaints_h)
+main.o: main.c $(defs_h) $(top_h) $(target_h) $(inferior_h) $(symfile_h) \
+       $(gdbcore_h) $(getopt_h) $(gdb_stat_h) $(gdb_string_h) \
+       $(event_loop_h) $(ui_out_h)
+maint.o: maint.c $(defs_h) $(command_h) $(gdbcmd_h) $(symtab_h) \
+       $(gdbtypes_h) $(demangle_h) $(gdbcore_h) $(expression_h) \
+       $(language_h) $(symfile_h) $(objfiles_h) $(value_h) $(cli_decode_h)
+mcore-rom.o: mcore-rom.c $(defs_h) $(gdbcore_h) $(target_h) $(monitor_h) \
+       $(gdb_string_h) $(regcache_h) $(serial_h)
+mcore-tdep.o: mcore-tdep.c $(defs_h) $(frame_h) $(symtab_h) $(value_h) \
+       $(gdbcmd_h) $(regcache_h) $(symfile_h) $(gdbcore_h) $(inferior_h) \
+       $(arch_utils_h)
+mdebugread.o: mdebugread.c $(defs_h) $(symtab_h) $(gdbtypes_h) $(gdbcore_h) \
+       $(symfile_h) $(objfiles_h) $(gdb_obstack_h) $(buildsym_h) \
+       $(stabsread_h) $(complaints_h) $(demangle_h) $(gdb_assert_h) \
+       $(coff_sym_h) $(coff_symconst_h) $(gdb_stat_h) $(gdb_string_h) \
+       $(bfd_h) $(coff_ecoff_h) $(libaout_h) $(aout_aout64_h) \
+       $(aout_stab_gnu_h) $(expression_h) $(language_h)
+mem-break.o: mem-break.c $(defs_h) $(symtab_h) $(breakpoint_h) $(inferior_h) \
+       $(target_h)
+memattr.o: memattr.c $(defs_h) $(command_h) $(gdbcmd_h) $(memattr_h) \
+       $(target_h) $(value_h) $(language_h) $(gdb_string_h)
+minsyms.o: minsyms.c $(defs_h) $(gdb_string_h) $(symtab_h) $(bfd_h) \
+       $(symfile_h) $(objfiles_h) $(demangle_h) $(value_h) $(cp_abi_h)
+mips-irix-tdep.o: mips-irix-tdep.c $(defs_h) $(osabi_h) $(elf_bfd_h)
+mips-linux-nat.o: mips-linux-nat.c $(defs_h)
+mips-linux-tdep.o: mips-linux-tdep.c $(defs_h) $(gdbcore_h) $(target_h) \
+       $(solib_svr4_h)
+mips-nat.o: mips-nat.c $(defs_h) $(inferior_h) $(gdbcore_h) $(regcache_h)
+mips-tdep.o: mips-tdep.c $(defs_h) $(gdb_string_h) $(frame_h) $(inferior_h) \
+       $(symtab_h) $(value_h) $(gdbcmd_h) $(language_h) $(gdbcore_h) \
+       $(symfile_h) $(objfiles_h) $(gdbtypes_h) $(target_h) $(arch_utils_h) \
+       $(regcache_h) $(osabi_h) $(opcode_mips_h) $(elf_mips_h) $(elf_bfd_h) \
+       $(symcat_h)
+mipsm3-nat.o: mipsm3-nat.c $(defs_h) $(inferior_h) $(regcache_h)
+mipsnbsd-nat.o: mipsnbsd-nat.c $(defs_h) $(inferior_h) $(regcache_h) \
+       $(mipsnbsd_tdep_h)
+mipsnbsd-tdep.o: mipsnbsd-tdep.c $(defs_h) $(gdbcore_h) $(regcache_h) \
+       $(target_h) $(value_h) $(osabi_h) $(mipsnbsd_tdep_h) $(solib_svr4_h) \
+       $(nbsd_tdep_h)
+mipsread.o: mipsread.c $(defs_h) $(gdb_string_h) $(bfd_h) $(symtab_h) \
+       $(symfile_h) $(objfiles_h) $(buildsym_h) $(stabsread_h) \
+       $(coff_sym_h) $(coff_internal_h) $(coff_ecoff_h) $(libcoff_h) \
+       $(libecoff_h) $(elf_common_h) $(elf_mips_h)
+mipsv4-nat.o: mipsv4-nat.c $(defs_h) $(inferior_h) $(gdbcore_h) $(target_h) \
+       $(regcache_h) $(gregset_h)
+mn10200-tdep.o: mn10200-tdep.c $(defs_h) $(frame_h) $(inferior_h) \
+       $(target_h) $(value_h) $(bfd_h) $(gdb_string_h) $(gdbcore_h) \
+       $(symfile_h) $(regcache_h)
+mn10300-tdep.o: mn10300-tdep.c $(defs_h) $(frame_h) $(inferior_h) \
+       $(target_h) $(value_h) $(bfd_h) $(gdb_string_h) $(gdbcore_h) \
+       $(symfile_h) $(regcache_h) $(arch_utils_h)
+mon960-rom.o: mon960-rom.c $(defs_h) $(gdbcore_h) $(target_h) $(monitor_h) \
+       $(serial_h) $(srec_h) $(xmodem_h) $(symtab_h) $(symfile_h) \
+       $(inferior_h) $(gdb_string_h)
+monitor.o: monitor.c $(defs_h) $(gdbcore_h) $(target_h) $(gdb_string_h) \
+       $(command_h) $(serial_h) $(monitor_h) $(gdbcmd_h) $(inferior_h) \
+       $(gdb_regex_h) $(srec_h) $(regcache_h)
+nbsd-tdep.o: nbsd-tdep.c $(defs_h) $(gdb_string_h) $(solib_svr4_h)
+nindy-tdep.o: nindy-tdep.c $(defs_h) $(symtab_h) $(frame_h) $(gdbcore_h)
+nlmread.o: nlmread.c $(defs_h) $(bfd_h) $(symtab_h) $(symfile_h) \
+       $(objfiles_h) $(buildsym_h) $(stabsread_h)
+ns32k-tdep.o: ns32k-tdep.c $(defs_h) $(frame_h) $(gdbtypes_h) $(gdbcore_h) \
+       $(inferior_h) $(regcache_h) $(target_h) $(arch_utils_h) \
+       $(ns32k_tdep_h)
+ns32knbsd-nat.o: ns32knbsd-nat.c $(defs_h) $(inferior_h) $(target_h) \
+       $(gdbcore_h) $(regcache_h)
+ns32knbsd-tdep.o: ns32knbsd-tdep.c $(defs_h) $(ns32k_tdep_h)
+objfiles.o: objfiles.c $(defs_h) $(bfd_h) $(symtab_h) $(symfile_h) \
+       $(objfiles_h) $(gdb_stabs_h) $(target_h) $(bcache_h) $(gdb_stat_h) \
+       $(gdb_obstack_h) $(gdb_string_h) $(breakpoint_h) $(mmalloc_h)
+ocd.o: ocd.c $(defs_h) $(gdbcore_h) $(gdb_string_h) $(frame_h) $(inferior_h) \
+       $(bfd_h) $(symfile_h) $(target_h) $(gdbcmd_h) $(objfiles_h) \
+       $(gdb_stabs_h) $(serial_h) $(ocd_h) $(regcache_h)
+op50-rom.o: op50-rom.c $(defs_h) $(gdbcore_h) $(target_h) $(monitor_h) \
+       $(serial_h)
+# OBSOLETE os9kread.o: os9kread.c
+osabi.o: osabi.c $(defs_h) $(gdb_string_h) $(osabi_h) $(elf_bfd_h)
+p-lang.o: p-lang.c $(defs_h) $(gdb_string_h) $(symtab_h) $(gdbtypes_h) \
+       $(expression_h) $(parser_defs_h) $(language_h) $(p_lang_h) \
+       $(valprint_h)
+p-typeprint.o: p-typeprint.c $(defs_h) $(gdb_obstack_h) $(bfd_h) $(symtab_h) \
+       $(gdbtypes_h) $(expression_h) $(value_h) $(gdbcore_h) $(target_h) \
+       $(language_h) $(p_lang_h) $(typeprint_h) $(gdb_string_h)
+p-valprint.o: p-valprint.c $(defs_h) $(gdb_obstack_h) $(symtab_h) \
+       $(gdbtypes_h) $(expression_h) $(value_h) $(command_h) $(gdbcmd_h) \
+       $(gdbcore_h) $(demangle_h) $(valprint_h) $(typeprint_h) \
+       $(language_h) $(target_h) $(annotate_h) $(p_lang_h) $(cp_abi_h)
+pa64solib.o: pa64solib.c $(defs_h) $(frame_h) $(bfd_h) $(libhppa_h) \
+       $(gdbcore_h) $(symtab_h) $(breakpoint_h) $(symfile_h) $(objfiles_h) \
+       $(inferior_h) $(gdb_stabs_h) $(gdb_stat_h) $(gdbcmd_h) $(language_h) \
+       $(regcache_h)
+parse.o: parse.c $(defs_h) $(gdb_string_h) $(symtab_h) $(gdbtypes_h) \
+       $(frame_h) $(expression_h) $(value_h) $(command_h) $(language_h) \
+       $(parser_defs_h) $(gdbcmd_h) $(symfile_h) $(inferior_h) \
+       $(doublest_h) $(builtin_regs_h) $(gdb_assert_h)
+ppc-bdm.o: ppc-bdm.c $(defs_h) $(gdbcore_h) $(gdb_string_h) $(frame_h) \
+       $(inferior_h) $(bfd_h) $(symfile_h) $(target_h) $(gdbcmd_h) \
+       $(objfiles_h) $(gdb_stabs_h) $(serial_h) $(ocd_h) $(ppc_tdep_h) \
+       $(regcache_h)
+ppc-linux-nat.o: ppc-linux-nat.c $(defs_h) $(frame_h) $(inferior_h) \
+       $(gdbcore_h) $(regcache_h) $(gregset_h) $(ppc_tdep_h)
+ppc-linux-tdep.o: ppc-linux-tdep.c $(defs_h) $(frame_h) $(inferior_h) \
+       $(symtab_h) $(target_h) $(gdbcore_h) $(gdbcmd_h) $(symfile_h) \
+       $(objfiles_h) $(regcache_h) $(value_h) $(solib_svr4_h) $(ppc_tdep_h)
+ppc-sysv-tdep.o: ppc-sysv-tdep.c $(defs_h) $(gdbcore_h) $(inferior_h) \
+       $(regcache_h) $(value_h) $(ppc_tdep_h)
+ppcbug-rom.o: ppcbug-rom.c $(defs_h) $(gdbcore_h) $(target_h) $(monitor_h) \
+       $(serial_h) $(regcache_h)
+ppcnbsd-nat.o: ppcnbsd-nat.c $(defs_h) $(inferior_h) $(ppc_tdep_h) \
+       $(ppcnbsd_tdep_h)
+ppcnbsd-tdep.o: ppcnbsd-tdep.c $(defs_h) $(gdbcore_h) $(regcache_h) \
+       $(target_h) $(breakpoint_h) $(value_h) $(ppc_tdep_h) \
+       $(ppcnbsd_tdep_h) $(nbsd_tdep_h) $(solib_svr4_h)
+printcmd.o: printcmd.c $(defs_h) $(gdb_string_h) $(frame_h) $(symtab_h) \
+       $(gdbtypes_h) $(value_h) $(language_h) $(expression_h) $(gdbcore_h) \
+       $(gdbcmd_h) $(target_h) $(breakpoint_h) $(demangle_h) $(valprint_h) \
+       $(annotate_h) $(symfile_h) $(objfiles_h) $(completer_h) $(ui_out_h) \
+       $(gdb_assert_h)
+proc-api.o: proc-api.c $(defs_h) $(gdbcmd_h) $(completer_h) $(proc_utils_h)
+proc-events.o: proc-events.c $(defs_h)
+proc-flags.o: proc-flags.c $(defs_h)
+proc-service.o: proc-service.c $(defs_h) $(gdb_proc_service_h) $(inferior_h) \
+       $(symtab_h) $(target_h) $(gregset_h)
+proc-why.o: proc-why.c $(defs_h) $(proc_utils_h)
+procfs.o: procfs.c $(defs_h) $(inferior_h) $(target_h) $(gdbcore_h) \
+       $(elf_bfd_h) $(gdbcmd_h) $(gdbthread_h) $(gdb_dirent_h) $(X_OK) \
+       $(gdb_stat_h) $(proc_utils_h) $(gregset_h)
+ptx4-nat.o: ptx4-nat.c $(defs_h) $(inferior_h) $(gdbcore_h) $(regcache_h) \
+       $(gregset_h)
+regcache.o: regcache.c $(defs_h) $(inferior_h) $(target_h) $(gdbarch_h) \
+       $(gdbcmd_h) $(regcache_h) $(gdb_assert_h) $(gdb_string_h) \
+       $(gdbcmd_h)
+remote-array.o: remote-array.c $(defs_h) $(gdbcore_h) $(target_h) \
+       $(gdb_string_h) $(command_h) $(serial_h) $(monitor_h) \
+       $(remote_utils_h) $(inferior_h) $(version_h) $(regcache_h)
+# OBSOLETE remote-bug.o: remote-bug.c
+remote-e7000.o: remote-e7000.c $(defs_h) $(gdbcore_h) $(gdbarch_h) \
+       $(inferior_h) $(target_h) $(value_h) $(command_h) $(gdb_string_h) \
+       $(gdbcmd_h) $(serial_h) $(remote_utils_h) $(symfile_h) $(regcache_h)
+remote-es.o: remote-es.c $(defs_h) $(gdb_string_h) $(frame_h) $(inferior_h) \
+       $(target_h) $(command_h) $(symfile_h) $(remote_utils_h) $(gdbcore_h) \
+       $(serial_h) $(regcache_h) $(value_h)
+remote-est.o: remote-est.c $(defs_h) $(gdbcore_h) $(target_h) $(monitor_h) \
+       $(serial_h) $(regcache_h)
+remote-hms.o: remote-hms.c $(defs_h) $(gdbcore_h) $(target_h) $(monitor_h) \
+       $(serial_h) $(regcache_h)
+remote-mips.o: remote-mips.c $(defs_h) $(inferior_h) $(bfd_h) $(symfile_h) \
+       $(gdbcmd_h) $(gdbcore_h) $(serial_h) $(target_h) $(remote_utils_h) \
+       $(gdb_string_h) $(gdb_stat_h) $(regcache_h)
+# OBSOLETE remote-nindy.o: remote-nindy.c
+# OBSOLETE remote-nrom.o: remote-nrom.c
+# OBSOLETE remote-os9k.o: remote-os9k.c
+remote-rdi.o: remote-rdi.c $(defs_h) $(gdb_string_h) $(frame_h) \
+       $(inferior_h) $(bfd_h) $(symfile_h) $(target_h) $(gdbcmd_h) \
+       $(objfiles_h) $(gdb_stabs_h) $(gdbthread_h) $(gdbcore_h) \
+       $(breakpoint_h) $(completer_h) $(regcache_h) $(arm_tdep_h) \
+       $(rdi_share_ardi_h) $(rdi_share_adp_h) $(rdi_share_hsys_h)
+remote-rdp.o: remote-rdp.c $(defs_h) $(inferior_h) $(value_h) \
+       $(gdb_callback_h) $(command_h) $(symfile_h) $(remote_utils_h) \
+       $(gdb_string_h) $(gdbcore_h) $(regcache_h) $(serial_h) $(arm_tdep_h)
+remote-sds.o: remote-sds.c $(defs_h) $(gdb_string_h) $(frame_h) \
+       $(inferior_h) $(bfd_h) $(symfile_h) $(target_h) $(gdbcmd_h) \
+       $(objfiles_h) $(gdb_stabs_h) $(gdbthread_h) $(gdbcore_h) \
+       $(regcache_h) $(serial_h)
+remote-sim.o: remote-sim.c $(defs_h) $(inferior_h) $(value_h) \
+       $(gdb_string_h) $(terminal_h) $(target_h) $(gdbcore_h) \
+       $(gdb_callback_h) $(gdb_remote_sim_h) $(remote_utils_h) $(command_h) \
+       $(regcache_h) $(gdb_assert_h) $(sim_regno_h)
+remote-st.o: remote-st.c $(defs_h) $(gdbcore_h) $(target_h) $(gdb_string_h) \
+       $(serial_h) $(regcache_h)
+remote-utils.o: remote-utils.c $(defs_h) $(gdb_string_h) $(gdbcmd_h) \
+       $(target_h) $(serial_h) $(gdbcore_h) $(inferior_h) $(remote_utils_h) \
+       $(regcache_h)
+remote-vx.o: remote-vx.c $(defs_h) $(frame_h) $(inferior_h) $(target_h) \
+       $(gdbcore_h) $(command_h) $(symtab_h) $(complaints_h) $(gdbcmd_h) \
+       $(bfd_h) $(symfile_h) $(objfiles_h) $(gdb_stabs_h) $(regcache_h) \
+       $(gdb_string_h) $(vx_share_ptrace_h) $(vx_share_xdr_ptrace_h) \
+       $(vx_share_xdr_ld_h) $(vx_share_xdr_rdb_h) $(vx_share_dbgRpcLib_h)
+remote-vx68.o: remote-vx68.c $(defs_h) $(vx_share_regPacket_h) $(frame_h) \
+       $(inferior_h) $(target_h) $(gdbcore_h) $(command_h) $(symtab_h) \
+       $(symfile_h) $(regcache_h) $(gdb_string_h) $(vx_share_ptrace_h) \
+       $(vx_share_xdr_ptrace_h) $(vx_share_xdr_ld_h) $(vx_share_xdr_rdb_h) \
+       $(vx_share_dbgRpcLib_h)
+# OBSOLETE remote-vx960.o: remote-vx960.c
+remote-vxmips.o: remote-vxmips.c $(defs_h) $(vx_share_regPacket_h) \
+       $(frame_h) $(inferior_h) $(target_h) $(gdbcore_h) $(command_h) \
+       $(symtab_h) $(symfile_h) $(regcache_h) $(gdb_string_h) \
+       $(vx_share_ptrace_h) $(vx_share_xdr_ptrace_h) $(vx_share_xdr_ld_h) \
+       $(vx_share_xdr_rdb_h) $(vx_share_dbgRpcLib_h)
+remote-vxsparc.o: remote-vxsparc.c $(defs_h) $(vx_share_regPacket_h) \
+       $(frame_h) $(inferior_h) $(target_h) $(gdbcore_h) $(command_h) \
+       $(symtab_h) $(symfile_h) $(regcache_h) $(gdb_string_h) \
+       $(vx_share_ptrace_h) $(vx_share_xdr_ptrace_h) $(vx_share_xdr_ld_h) \
+       $(vx_share_xdr_rdb_h) $(vx_share_dbgRpcLib_h)
+remote.o: remote.c $(defs_h) $(gdb_string_h) $(inferior_h) $(bfd_h) \
+       $(symfile_h) $(target_h) $(gdbcmd_h) $(objfiles_h) $(gdb_stabs_h) \
+       $(gdbthread_h) $(remote_h) $(regcache_h) $(value_h) $(gdb_assert_h) \
+       $(event_loop_h) $(event_top_h) $(inf_loop_h) $(serial_h) \
+       $(gdbcore_h)
+rom68k-rom.o: rom68k-rom.c $(defs_h) $(gdbcore_h) $(target_h) $(monitor_h) \
+       $(serial_h) $(regcache_h) $(value_h)
+rs6000-nat.o: rs6000-nat.c $(defs_h) $(inferior_h) $(target_h) $(gdbcore_h) \
+       $(xcoffsolib_h) $(symfile_h) $(objfiles_h) $(libbfd_h) $(bfd_h) \
+       $(gdb_stabs_h) $(regcache_h) $(arch_utils_h) $(language_h) \
+       $(ppc_tdep_h) $(gdb_stat_h)
+rs6000-tdep.o: rs6000-tdep.c $(defs_h) $(frame_h) $(inferior_h) $(symtab_h) \
+       $(target_h) $(gdbcore_h) $(gdbcmd_h) $(symfile_h) $(objfiles_h) \
+       $(arch_utils_h) $(regcache_h) $(doublest_h) $(value_h) \
+       $(parser_defs_h) $(libbfd_h) $(coff_internal_h) $(libcoff_h) \
+       $(coff_xcoff_h) $(libxcoff_h) $(elf_bfd_h) $(solib_svr4_h) \
+       $(ppc_tdep_h)
+s390-nat.o: s390-nat.c $(defs_h) $(tm_h) $(regcache_h)
+s390-tdep.o: s390-tdep.c $(arch_utils_h) $(frame_h) $(inferior_h) \
+       $(symtab_h) $(target_h) $(gdbcore_h) $(gdbcmd_h) $(symfile_h) \
+       $(objfiles_h) $(tm_h) $(__bfd_bfd_h) $(floatformat_h) $(regcache_h) \
+       $(value_h) $(gdb_assert_h)
+scm-exp.o: scm-exp.c $(defs_h) $(symtab_h) $(gdbtypes_h) $(expression_h) \
+       $(parser_defs_h) $(language_h) $(value_h) $(c_lang_h) $(scm_lang_h) \
+       $(scm_tags_h)
+scm-lang.o: scm-lang.c $(defs_h) $(symtab_h) $(gdbtypes_h) $(expression_h) \
+       $(parser_defs_h) $(language_h) $(value_h) $(c_lang_h) $(scm_lang_h) \
+       $(scm_tags_h) $(gdb_string_h) $(gdbcore_h) $(source_h)
+scm-valprint.o: scm-valprint.c $(defs_h) $(symtab_h) $(gdbtypes_h) \
+       $(expression_h) $(parser_defs_h) $(language_h) $(value_h) \
+       $(scm_lang_h) $(valprint_h) $(gdbcore_h)
+ser-e7kpc.o: ser-e7kpc.c $(defs_h) $(serial_h) $(gdb_string_h)
+ser-go32.o: ser-go32.c $(defs_h) $(gdbcmd_h) $(serial_h) $(gdb_string_h)
+ser-pipe.o: ser-pipe.c $(defs_h) $(serial_h) $(ser_unix_h) $(gdb_vfork_h) \
+       $(gdb_string_h)
+ser-tcp.o: ser-tcp.c $(defs_h) $(serial_h) $(ser_unix_h) $(gdb_string_h)
+ser-unix.o: ser-unix.c $(defs_h) $(serial_h) $(ser_unix_h) $(terminal_h) \
+       $(gdb_string_h) $(event_loop_h)
+serial.o: serial.c $(defs_h) $(serial_h) $(gdb_string_h) $(gdbcmd_h)
+sh-stub.o: sh-stub.c
+sh-tdep.o: sh-tdep.c $(defs_h) $(frame_h) $(symtab_h) $(symfile_h) \
+       $(gdbtypes_h) $(gdbcmd_h) $(gdbcore_h) $(value_h) $(dis_asm_h) \
+       $(inferior_h) $(gdb_string_h) $(arch_utils_h) $(floatformat_h) \
+       $(regcache_h) $(doublest_h) $(sh_tdep_h) $(elf_bfd_h) \
+       $(solib_svr4_h) $(elf_sh_h) $(gdb_sim_sh_h)
+sh3-rom.o: sh3-rom.c $(defs_h) $(gdbcore_h) $(target_h) $(monitor_h) \
+       $(serial_h) $(srec_h) $(arch_utils_h) $(regcache_h) $(sh_tdep_h)
+shnbsd-nat.o: shnbsd-nat.c $(defs_h) $(inferior_h) $(shnbsd_tdep_h)
+shnbsd-tdep.o: shnbsd-tdep.c $(defs_h) $(gdbcore_h) $(regcache_h) $(value_h) \
+       $(solib_svr4_h) $(nbsd_tdep_h) $(sh_tdep_h) $(shnbsd_tdep_h)
+sol-thread.o: sol-thread.c $(defs_h) $(gdbthread_h) $(target_h) \
+       $(inferior_h) $(gdbcmd_h) $(gdbcore_h) $(regcache_h) $(symfile_h) \
+       $(gregset_h)
+solib-aix5.o: solib-aix5.c $(defs_h) $(gdb_string_h) $(elf_external_h) \
+       $(symtab_h) $(bfd_h) $(symfile_h) $(objfiles_h) $(gdbcore_h) \
+       $(command_h) $(target_h) $(frame_h) $(gdb_regex_h) $(inferior_h) \
+       $(environ_h) $(language_h) $(gdbcmd_h) $(solist_h)
+solib-irix.o: solib-irix.c $(defs_h) $(symtab_h) $(bfd_h) $(symfile_h) \
+       $(objfiles_h) $(gdbcore_h) $(target_h) $(inferior_h) $(solist_h)
+solib-legacy.o: solib-legacy.c $(defs_h) $(gdbcore_h) $(solib_svr4_h)
+solib-osf.o: solib-osf.c $(defs_h) $(gdb_string_h) $(bfd_h) $(symtab_h) \
+       $(symfile_h) $(objfiles_h) $(target_h) $(inferior_h) $(solist_h)
+solib-sunos.o: solib-sunos.c $(defs_h) $(gdb_string_h) $(symtab_h) $(bfd_h) \
+       $(symfile_h) $(objfiles_h) $(gdbcore_h) $(inferior_h) $(solist_h)
+solib-svr4.o: solib-svr4.c $(defs_h) $(elf_external_h) $(elf_common_h) \
+       $(elf_mips_h) $(symtab_h) $(bfd_h) $(symfile_h) $(objfiles_h) \
+       $(gdbcore_h) $(target_h) $(inferior_h) $(solist_h) $(solib_svr4_h)
+solib.o: solib.c $(defs_h) $(gdb_string_h) $(symtab_h) $(bfd_h) $(symfile_h) \
+       $(objfiles_h) $(gdbcore_h) $(command_h) $(target_h) $(frame_h) \
+       $(gdb_regex_h) $(inferior_h) $(environ_h) $(language_h) $(gdbcmd_h) \
+       $(completer_h) $(filenames_h) $(solist_h)
+somread.o: somread.c $(defs_h) $(bfd_h) $(symtab_h) $(symfile_h) \
+       $(objfiles_h) $(buildsym_h) $(stabsread_h) $(gdb_stabs_h) \
+       $(complaints_h) $(gdb_string_h) $(demangle_h) $(som_h) $(libhppa_h)
+somsolib.o: somsolib.c $(defs_h) $(frame_h) $(bfd_h) $(som_h) $(libhppa_h) \
+       $(gdbcore_h) $(symtab_h) $(breakpoint_h) $(symfile_h) $(objfiles_h) \
+       $(inferior_h) $(gdb_stabs_h) $(gdb_stat_h) $(gdbcmd_h) $(language_h) \
+       $(regcache_h)
+source.o: source.c $(defs_h) $(symtab_h) $(expression_h) $(language_h) \
+       $(command_h) $(source_h) $(gdbcmd_h) $(frame_h) $(value_h) \
+       $(gdb_string_h) $(gdb_stat_h) $(gdbcore_h) $(gdb_regex_h) \
+       $(symfile_h) $(objfiles_h) $(annotate_h) $(gdbtypes_h) $(linespec_h) \
+       $(filenames_h) $(completer_h) $(ui_out_h)
+sparc-linux-nat.o: sparc-linux-nat.c $(defs_h) $(regcache_h) $(gregset_h)
+sparc-nat.o: sparc-nat.c $(defs_h) $(inferior_h) $(target_h) $(gdbcore_h) \
+       $(regcache_h)
+sparc-stub.o: sparc-stub.c
+sparc-tdep.o: sparc-tdep.c $(defs_h) $(arch_utils_h) $(frame_h) \
+       $(inferior_h) $(target_h) $(value_h) $(bfd_h) $(gdb_string_h) \
+       $(regcache_h) $(osabi_h) $(gregset_h) $(gdbcore_h) $(symfile_h)
+sparc64nbsd-nat.o: sparc64nbsd-nat.c $(defs_h) $(inferior_h) $(regcache_h) \
+       $(sparcnbsd_tdep_h)
+sparcl-stub.o: sparcl-stub.c
+sparcl-tdep.o: sparcl-tdep.c $(defs_h) $(gdbcore_h) $(breakpoint_h) \
+       $(target_h) $(serial_h) $(regcache_h)
+sparclet-rom.o: sparclet-rom.c $(defs_h) $(gdbcore_h) $(target_h) \
+       $(monitor_h) $(serial_h) $(srec_h) $(symtab_h) $(symfile_h) \
+       $(regcache_h)
+sparclet-stub.o: sparclet-stub.c
+sparcnbsd-nat.o: sparcnbsd-nat.c $(defs_h) $(inferior_h) $(regcache_h) \
+       $(sparcnbsd_tdep_h)
+sparcnbsd-tdep.o: sparcnbsd-tdep.c $(defs_h) $(gdbcore_h) $(regcache_h) \
+       $(target_h) $(value_h) $(osabi_h) $(sparcnbsd_tdep_h) $(nbsd_tdep_h) \
+       $(solib_svr4_h)
+stabsread.o: stabsread.c $(defs_h) $(gdb_string_h) $(bfd_h) $(gdb_obstack_h) \
+       $(symtab_h) $(gdbtypes_h) $(expression_h) $(symfile_h) $(objfiles_h) \
+       $(aout_stab_gnu_h) $(libaout_h) $(aout_aout64_h) $(gdb_stabs_h) \
+       $(buildsym_h) $(complaints_h) $(demangle_h) $(language_h) \
+       $(doublest_h) $(stabsread_h) $(cp_abi_h) $(cp_support_h)
+stack.o: stack.c $(defs_h) $(gdb_string_h) $(value_h) $(symtab_h) \
+       $(gdbtypes_h) $(expression_h) $(language_h) $(frame_h) $(gdbcmd_h) \
+       $(gdbcore_h) $(target_h) $(breakpoint_h) $(demangle_h) $(inferior_h) \
+       $(annotate_h) $(ui_out_h) $(source_h)
+standalone.o: standalone.c $(gdb_stat_h) $(defs_h) $(symtab_h) $(frame_h) \
+       $(inferior_h) $(gdb_wait_h)
+std-regs.o: std-regs.c $(defs_h) $(builtin_regs_h) $(frame_h) $(gdbtypes_h) \
+       $(value_h) $(gdb_string_h)
+stop-gdb.o: stop-gdb.c $(defs_h)
+sun3-nat.o: sun3-nat.c $(defs_h) $(inferior_h) $(gdbcore_h) $(regcache_h)
+symfile.o: symfile.c $(defs_h) $(symtab_h) $(gdbtypes_h) $(gdbcore_h) \
+       $(frame_h) $(target_h) $(value_h) $(symfile_h) $(objfiles_h) \
+       $(gdbcmd_h) $(breakpoint_h) $(language_h) $(complaints_h) \
+       $(demangle_h) $(inferior_h) $(gdb_stabs_h) $(gdb_obstack_h) \
+       $(completer_h) $(bcache_h) $(gdb_string_h) $(gdb_stat_h) $(source_h)
+symm-nat.o: symm-nat.c $(defs_h) $(frame_h) $(inferior_h) $(symtab_h) \
+       $(target_h) $(regcache_h) $(gdb_stat_h) $(gdbcore_h) $(gdbcore_h)
+symm-tdep.o: symm-tdep.c $(defs_h) $(frame_h) $(inferior_h) $(symtab_h) \
+       $(gdb_stat_h) $(gdbcore_h)
+symmisc.o: symmisc.c $(defs_h) $(symtab_h) $(gdbtypes_h) $(bfd_h) \
+       $(symfile_h) $(objfiles_h) $(breakpoint_h) $(command_h) \
+       $(gdb_obstack_h) $(language_h) $(bcache_h) $(gdb_string_h)
+symtab.o: symtab.c $(defs_h) $(symtab_h) $(gdbtypes_h) $(gdbcore_h) \
+       $(frame_h) $(target_h) $(value_h) $(symfile_h) $(objfiles_h) \
+       $(gdbcmd_h) $(call_cmds_h) $(gdb_regex_h) $(expression_h) \
+       $(language_h) $(demangle_h) $(inferior_h) $(linespec_h) \
+       $(filenames_h) $(gdb_obstack_h) $(gdb_string_h) $(gdb_stat_h) \
+       $(cp_abi_h) $(source_h)
+target.o: target.c $(defs_h) $(gdb_string_h) $(target_h) $(gdbcmd_h) \
+       $(symtab_h) $(inferior_h) $(bfd_h) $(symfile_h) $(objfiles_h) \
+       $(gdb_wait_h) $(dcache_h) $(regcache_h)
+thread-db.o: thread-db.c $(defs_h) $(gdb_assert_h) $(gdb_proc_service_h) \
+       $(gdb_thread_db_h) $(bfd_h) $(gdbthread_h) $(inferior_h) \
+       $(symfile_h) $(objfiles_h) $(target_h) $(regcache_h)
+thread.o: thread.c $(defs_h) $(symtab_h) $(frame_h) $(inferior_h) \
+       $(environ_h) $(value_h) $(target_h) $(gdbthread_h) $(command_h) \
+       $(gdbcmd_h) $(regcache_h) $(gdb_h) $(gdb_string_h) $(ui_out_h)
+top.o: top.c $(defs_h) $(gdbcmd_h) $(call_cmds_h) $(cli_cmds_h) \
+       $(cli_script_h) $(cli_setshow_h) $(cli_decode_h) $(symtab_h) \
+       $(inferior_h) $(target_h) $(breakpoint_h) $(gdbtypes_h) \
+       $(expression_h) $(value_h) $(language_h) $(terminal_h) $(annotate_h) \
+       $(completer_h) $(top_h) $(version_h) $(serial_h) $(doublest_h) \
+       $(gdb_assert_h) $(event_top_h) $(gdb_string_h) $(gdb_stat_h) \
+       $(ui_out_h) $(cli_out_h)
+tracepoint.o: tracepoint.c $(defs_h) $(symtab_h) $(frame_h) $(gdbtypes_h) \
+       $(expression_h) $(gdbcmd_h) $(value_h) $(target_h) $(language_h) \
+       $(gdb_string_h) $(inferior_h) $(tracepoint_h) $(remote_h) \
+       $(linespec_h) $(regcache_h) $(completer_h) $(gdb_events_h) $(ax_h) \
+       $(ax_gdb_h)
+typeprint.o: typeprint.c $(defs_h) $(gdb_obstack_h) $(bfd_h) $(symtab_h) \
+       $(gdbtypes_h) $(expression_h) $(value_h) $(gdbcore_h) $(command_h) \
+       $(gdbcmd_h) $(target_h) $(language_h) $(cp_abi_h) $(gdb_string_h)
+ui-file.o: ui-file.c $(defs_h) $(ui_file_h) $(gdb_string_h)
+ui-out.o: ui-out.c $(defs_h) $(gdb_string_h) $(expression_h) $(language_h) \
+       $(ui_out_h) $(gdb_assert_h)
+utils.o: utils.c $(config_h) $(defs_h) $(gdb_assert_h) $(gdb_string_h) \
+       $(event_top_h) $(gdbcmd_h) $(serial_h) $(bfd_h) $(target_h) \
+       $(demangle_h) $(expression_h) $(language_h) $(annotate_h) \
+       $(filenames_h) $(inferior_h) $(mmalloc_h)
+uw-thread.o: uw-thread.c $(defs_h) $(gdbthread_h) $(target_h) $(inferior_h) \
+       $(regcache_h) $(gregset_h)
+v850-tdep.o: v850-tdep.c $(defs_h) $(frame_h) $(inferior_h) $(target_h) \
+       $(value_h) $(bfd_h) $(gdb_string_h) $(gdbcore_h) $(symfile_h) \
+       $(arch_utils_h) $(regcache_h) $(symtab_h)
+v850ice.o: v850ice.c $(defs_h) $(gdb_string_h) $(frame_h) $(symtab_h) \
+       $(inferior_h) $(breakpoint_h) $(symfile_h) $(target_h) $(objfiles_h) \
+       $(gdbcore_h) $(value_h) $(command_h) $(regcache_h)
+valarith.o: valarith.c $(defs_h) $(value_h) $(symtab_h) $(gdbtypes_h) \
+       $(expression_h) $(target_h) $(language_h) $(gdb_string_h) \
+       $(doublest_h)
+valops.o: valops.c $(defs_h) $(symtab_h) $(gdbtypes_h) $(value_h) $(frame_h) \
+       $(inferior_h) $(gdbcore_h) $(target_h) $(demangle_h) $(language_h) \
+       $(gdbcmd_h) $(regcache_h) $(cp_abi_h) $(gdb_string_h) \
+       $(gdb_assert_h)
+valprint.o: valprint.c $(defs_h) $(gdb_string_h) $(symtab_h) $(gdbtypes_h) \
+       $(value_h) $(gdbcore_h) $(gdbcmd_h) $(target_h) $(language_h) \
+       $(annotate_h) $(valprint_h) $(floatformat_h) $(doublest_h)
+values.o: values.c $(defs_h) $(gdb_string_h) $(symtab_h) $(gdbtypes_h) \
+       $(value_h) $(gdbcore_h) $(command_h) $(gdbcmd_h) $(target_h) \
+       $(language_h) $(scm_lang_h) $(demangle_h) $(doublest_h) \
+       $(gdb_assert_h) $(regcache_h)
+varobj.o: varobj.c $(defs_h) $(value_h) $(expression_h) $(frame_h) \
+       $(language_h) $(wrapper_h) $(gdbcmd_h) $(gdb_string_h) $(varobj_h)
+vax-tdep.o: vax-tdep.c $(defs_h) $(symtab_h) $(opcode_vax_h) $(gdbcore_h) \
+       $(inferior_h) $(regcache_h) $(frame_h) $(value_h) $(arch_utils_h) \
+       $(vax_tdep_h)
+w89k-rom.o: w89k-rom.c $(defs_h) $(gdbcore_h) $(target_h) $(monitor_h) \
+       $(serial_h) $(xmodem_h) $(regcache_h)
+win32-nat.o: win32-nat.c $(defs_h) $(tm_h) $(frame_h) $(inferior_h) \
+       $(target_h) $(gdbcore_h) $(command_h) $(completer_h) $(regcache_h) \
+       $(top_h) $(i386_tdep_h) $(buildsym_h) $(symfile_h) $(objfiles_h) \
+       $(gdb_string_h) $(gdbthread_h) $(gdbcmd_h)
+wince-stub.o: wince-stub.c $(wince_stub_h)
+wince.o: wince.c $(defs_h) $(frame_h) $(inferior_h) $(target_h) $(gdbcore_h) \
+       $(command_h) $(buildsym_h) $(symfile_h) $(objfiles_h) \
+       $(gdb_string_h) $(gdbthread_h) $(gdbcmd_h) $(wince_stub_h) \
+       $(regcache_h)
+wrapper.o: wrapper.c $(defs_h) $(value_h) $(wrapper_h)
+x86-64-linux-nat.o: x86-64-linux-nat.c $(defs_h) $(inferior_h) $(gdbcore_h) \
+       $(regcache_h) $(gdb_assert_h) $(x86_64_tdep_h)
+x86-64-linux-tdep.o: x86-64-linux-tdep.c $(defs_h) $(inferior_h) \
+       $(gdbcore_h) $(regcache_h) $(x86_64_tdep_h) $(dwarf2cfi_h)
+x86-64-tdep.o: x86-64-tdep.c $(defs_h) $(inferior_h) $(gdbcore_h) \
+       $(gdbcmd_h) $(arch_utils_h) $(regcache_h) $(symfile_h) $(objfiles_h) \
+       $(x86_64_tdep_h) $(dwarf2cfi_h) $(gdb_assert_h)
+xcoffread.o: xcoffread.c $(defs_h) $(bfd_h) $(gdb_string_h) $(gdb_stat_h) \
+       $(coff_internal_h) $(libcoff_h) $(coff_xcoff_h) $(libxcoff_h) \
+       $(coff_rs6000_h) $(symtab_h) $(gdbtypes_h) $(symfile_h) \
+       $(objfiles_h) $(buildsym_h) $(stabsread_h) $(expression_h) \
+       $(complaints_h) $(gdb_stabs_h) $(aout_stab_gnu_h)
+xcoffsolib.o: xcoffsolib.c $(defs_h) $(bfd_h) $(xcoffsolib_h) $(inferior_h) \
+       $(gdbcmd_h) $(symfile_h) $(frame_h) $(gdb_regex_h)
+xmodem.o: xmodem.c $(defs_h) $(serial_h) $(target_h) $(xmodem_h)
+xstormy16-tdep.o: xstormy16-tdep.c $(defs_h) $(value_h) $(inferior_h) \
+       $(symfile_h) $(arch_utils_h) $(regcache_h) $(gdbcore_h) \
+       $(objfiles_h)
+z8k-tdep.o: z8k-tdep.c $(defs_h) $(frame_h) $(symtab_h) $(gdbcmd_h) \
+       $(gdbtypes_h) $(dis_asm_h) $(gdbcore_h) $(regcache_h) $(value_h)
+
+#
+# gdb/cli/ dependencies
+#
+# Need to explicitly specify the compile rule as make will do nothing
+# or try to compile the object file into the mi directory.
+
+cli-cmds.o: $(srcdir)/cli/cli-cmds.c $(defs_h) $(completer_h) $(target_h) \
+       $(gdb_wait_h) $(gdb_regex_h) $(gdb_string_h) $(filenames_h) \
+       $(ui_out_h) $(top_h) $(cli_decode_h) $(cli_script_h) \
+       $(cli_setshow_h) $(cli_cmds_h) $(source_h) $(linespec_h) \
+       $(expression_h) $(language_h) $(objfiles_h)
+       $(CC) -c $(INTERNAL_CFLAGS) $(srcdir)/cli/cli-cmds.c
+cli-decode.o: $(srcdir)/cli/cli-decode.c $(defs_h) $(symtab_h) \
+       $(gdb_regex_h) $(gdb_string_h) $(ui_out_h) $(cli_cmds_h) \
+       $(cli_decode_h) $(gdb_assert_h)
+       $(CC) -c $(INTERNAL_CFLAGS) $(srcdir)/cli/cli-decode.c
+cli-dump.o: $(srcdir)/cli/cli-dump.c $(defs_h) $(gdb_string_h) \
+       $(cli_decode_h) $(cli_cmds_h) $(value_h) $(completer_h) \
+       $(cli_dump_h) $(gdb_assert_h) $(target_h)
+       $(CC) -c $(INTERNAL_CFLAGS) $(srcdir)/cli/cli-dump.c
+cli-script.o: $(srcdir)/cli/cli-script.c $(defs_h) $(value_h) $(language_h) \
+       $(ui_out_h) $(gdb_string_h) $(top_h) $(cli_cmds_h) $(cli_decode_h) \
+       $(cli_script_h)
+       $(CC) -c $(INTERNAL_CFLAGS) $(srcdir)/cli/cli-script.c
+cli-setshow.o: $(srcdir)/cli/cli-setshow.c $(defs_h) $(value_h) \
+       $(gdb_string_h) $(ui_out_h) $(cli_decode_h) $(cli_cmds_h) \
+       $(cli_setshow_h)
+       $(CC) -c $(INTERNAL_CFLAGS) $(srcdir)/cli/cli-setshow.c
+cli-utils.o: $(srcdir)/cli/cli-utils.c $(defs_h) $(cli_utils_h)
+       $(CC) -c $(INTERNAL_CFLAGS) $(srcdir)/cli/cli-utils.c
+
+#
+# GDBTK sub-directory
+#
+# Need to explicitly specify the compile rule as make will do nothing
+# or try to compile the object file into the mi directory.
+
+gdbres.o: $(srcdir)/gdbtk/gdb.rc $(srcdir)/gdbtk/gdbtool.ico
+       $(WINDRES) --include $(srcdir)/gdbtk $(srcdir)/gdbtk/gdb.rc gdbres.o
+
+gdbtk.o: $(srcdir)/gdbtk/generic/gdbtk.c \
+       $(srcdir)/gdbtk/generic/gdbtk.h $(defs_h) \
+       $(symtab_h) $(inferior_h) $(command_h) \
+       $(bfd_h) $(symfile_h) $(objfiles_h) $(target_h) $(gdb_string_h) \
+       $(tracepoint_h) $(top_h) 
+       $(CC) -c $(INTERNAL_CFLAGS) $(IDE_CFLAGS) $(ITCL_CFLAGS) \
+        $(ITK_CFLAGS) $(TIX_CFLAGS) \
+       $(TCL_CFLAGS) $(TK_CFLAGS) $(X11_CFLAGS) $(GDBTK_CFLAGS)\
+               $(srcdir)/gdbtk/generic/gdbtk.c \
+               -DGDBTK_LIBRARY=\"$(GDBTK_LIBRARY)\" -DSRC_DIR=\"$(GDBTK_SRC_DIR)\"
+
+gdbtk-bp.o: $(srcdir)/gdbtk/generic/gdbtk-bp.c \
+               $(srcdir)/gdbtk/generic/gdbtk.h \
+               $(srcdir)/gdbtk/generic/gdbtk-cmds.h \
+               $(defs_h) $(breakpoint_h) $(tracepoint_h) \
+               $(symfile_h) $(symtab_h) $(gdb_string_h)
+       $(CC) -c $(INTERNAL_CFLAGS) $(IDE_CFLAGS) $(ITCL_CFLAGS) \
+       $(TIX_CFLAGS) $(TCL_CFLAGS) $(TK_CFLAGS) $(X11_CFLAGS)   \
+       $(GDBTK_CFLAGS) $(srcdir)/gdbtk/generic/gdbtk-bp.c \
+       -DGDBTK_LIBRARY=\"$(GDBTK_LIBRARY)\"
+
+gdbtk-cmds.o: $(srcdir)/gdbtk/generic/gdbtk-cmds.c \
+       $(srcdir)/gdbtk/generic/gdbtk.h $(srcdir)/gdbtk/generic/gdbtk-cmds.h \
+       $(defs_h) $(symtab_h) $(inferior_h)     \
+       $(command_h) $(bfd_h) $(top_h) $(symfile_h) $(objfiles_h) $(target_h) \
+       $(gdb_string_h) $(tracepoint_h) $(source_h) $(regcache_h)
+       $(CC) -c $(INTERNAL_CFLAGS) $(IDE_CFLAGS) $(ITCL_CFLAGS)        \
+       $(TIX_CFLAGS) $(TCL_CFLAGS) $(TK_CFLAGS) $(X11_CFLAGS)          \
+       $(GDBTK_CFLAGS) $(srcdir)/gdbtk/generic/gdbtk-cmds.c            \
+       -DGDBTK_LIBRARY=\"$(GDBTK_LIBRARY)\"
+
+gdbtk-hooks.o: $(srcdir)/gdbtk/generic/gdbtk-hooks.c \
+       $(srcdir)/gdbtk/generic/gdbtk.h $(defs_h) \
+       $(symtab_h) $(inferior_h) $(command_h) \
+       $(bfd_h) $(symfile_h) $(objfiles_h) $(target_h) $(gdb_string_h) \
+       $(tracepoint_h)
+       $(CC) -c $(INTERNAL_CFLAGS) $(IDE_CFLAGS) $(ITCL_CFLAGS) $(TIX_CFLAGS) \
+       $(TCL_CFLAGS) $(TK_CFLAGS) $(X11_CFLAGS) $(GDBTK_CFLAGS)\
+               $(srcdir)/gdbtk/generic/gdbtk-hooks.c -DGDBTK_LIBRARY=\"$(GDBTK_LIBRARY)\"
+
+gdbtk-register.o: $(srcdir)/gdbtk/generic/gdbtk-register.c \
+               $(srcdir)/gdbtk/generic/gdbtk.h \
+               $(srcdir)/gdbtk/generic/gdbtk-cmds.h \
+               $(defs_h) $(frame_h) $(value_h) $(gdb_string_h)
+       $(CC) -c $(INTERNAL_CFLAGS) $(IDE_CFLAGS) $(ITCL_CFLAGS) \
+       $(TIX_CFLAGS) $(TCL_CFLAGS) $(TK_CFLAGS) $(X11_CFLAGS)   \
+       $(GDBTK_CFLAGS) $(srcdir)/gdbtk/generic/gdbtk-register.c \
+       -DGDBTK_LIBRARY=\"$(GDBTK_LIBRARY)\"
+
+gdbtk-stack.o: $(srcdir)/gdbtk/generic/gdbtk-stack.c \
+       $(srcdir)/gdbtk/generic/gdbtk.h $(srcdir)/gdbtk/generic/gdbtk-cmds.h \
+       $(srcdir)/gdbtk/generic/gdbtk-wrapper.h \
+       $(defs_h) $(frame_h) $(value_h) $(target_h) $(breakpoint_h) \
+       $(linespec_h)
+       $(CC) -c $(INTERNAL_CFLAGS) $(IDE_CFLAGS) $(ITCL_CFLAGS) \
+       $(TIX_CFLAGS) $(TCL_CFLAGS) $(TK_CFLAGS) $(X11_CFLAGS)   \
+       $(GDBTK_CFLAGS) $(srcdir)/gdbtk/generic/gdbtk-stack.c \
+       -DGDBTK_LIBRARY=\"$(GDBTK_LIBRARY)\"
+
+gdbtk-varobj.o: $(srcdir)/gdbtk/generic/gdbtk-varobj.c \
+               $(srcdir)/gdbtk/generic/gdbtk.h \
+               $(defs_h) $(value_h) $(varobj_h) $(gdb_string_h)
+       $(CC) -c $(INTERNAL_CFLAGS) $(IDE_CFLAGS) $(ITCL_CFLAGS) $(TIX_CFLAGS) \
+       $(TCL_CFLAGS) $(TK_CFLAGS) $(X11_CFLAGS) $(GDBTK_CFLAGS)\
+               $(srcdir)/gdbtk/generic/gdbtk-varobj.c
+
+gdbtk-wrapper.o: $(srcdir)/gdbtk/generic/gdbtk-wrapper.c \
+       $(srcdir)/gdbtk/generic/gdbtk-wrapper.h \
+       $(defs_h) $(frame_h) $(value_h)
+       $(CC) -c $(INTERNAL_CFLAGS) $(IDE_CFLAGS) $(GDBTK_CFLAGS)\
+               $(srcdir)/gdbtk/generic/gdbtk-wrapper.c
+
+#
+# gdb/mi/ dependencies
+#
+# Need to explicitly specify the compile rule as make will do nothing
+# or try to compile the object file into the mi directory.
+
+mi-cmd-break.o: $(srcdir)/mi/mi-cmd-break.c $(defs_h) $(mi_cmds_h) \
+       $(ui_out_h) $(mi_out_h) $(breakpoint_h) $(gdb_string_h) \
+       $(mi_getopt_h) $(gdb_events_h) $(gdb_h)
+       $(CC) -c $(INTERNAL_CFLAGS) $(srcdir)/mi/mi-cmd-break.c
+mi-cmd-disas.o: $(srcdir)/mi/mi-cmd-disas.c $(defs_h) $(target_h) $(value_h) \
+       $(mi_cmds_h) $(mi_getopt_h) $(ui_out_h) $(gdb_string_h)
+       $(CC) -c $(INTERNAL_CFLAGS) $(srcdir)/mi/mi-cmd-disas.c
+mi-cmd-stack.o: $(srcdir)/mi/mi-cmd-stack.c $(defs_h) $(target_h) $(frame_h) \
+       $(value_h) $(mi_cmds_h) $(ui_out_h) $(symtab_h)
+       $(CC) -c $(INTERNAL_CFLAGS) $(srcdir)/mi/mi-cmd-stack.c
+mi-cmd-var.o: $(srcdir)/mi/mi-cmd-var.c $(defs_h) $(mi_cmds_h) $(ui_out_h) \
+       $(mi_out_h) $(varobj_h) $(value_h) $(gdb_string_h)
+       $(CC) -c $(INTERNAL_CFLAGS) $(srcdir)/mi/mi-cmd-var.c
+mi-cmds.o: $(srcdir)/mi/mi-cmds.c $(defs_h) $(top_h) $(mi_cmds_h) \
+       $(gdb_string_h)
+       $(CC) -c $(INTERNAL_CFLAGS) $(srcdir)/mi/mi-cmds.c
+mi-console.o: $(srcdir)/mi/mi-console.c $(defs_h) $(mi_console_h) \
+       $(gdb_string_h)
+       $(CC) -c $(INTERNAL_CFLAGS) $(srcdir)/mi/mi-console.c
+mi-getopt.o: $(srcdir)/mi/mi-getopt.c $(defs_h) $(mi_getopt_h) \
+       $(gdb_string_h)
+       $(CC) -c $(INTERNAL_CFLAGS) $(srcdir)/mi/mi-getopt.c
+mi-main.o: $(srcdir)/mi/mi-main.c $(defs_h) $(target_h) $(inferior_h) \
+       $(gdb_string_h) $(top_h) $(gdbthread_h) $(mi_cmds_h) $(mi_parse_h) \
+       $(mi_getopt_h) $(mi_console_h) $(ui_out_h) $(mi_out_h) \
+       $(event_loop_h) $(event_top_h) $(gdbcore_h) $(value_h) $(regcache_h) \
+       $(gdb_h)
+       $(CC) -c $(INTERNAL_CFLAGS) $(srcdir)/mi/mi-main.c
+mi-out.o: $(srcdir)/mi/mi-out.c $(defs_h) $(ui_out_h) $(mi_out_h)
+       $(CC) -c $(INTERNAL_CFLAGS) $(srcdir)/mi/mi-out.c
+mi-parse.o: $(srcdir)/mi/mi-parse.c $(defs_h) $(mi_cmds_h) $(mi_parse_h) \
+       $(gdb_string_h)
+       $(CC) -c $(INTERNAL_CFLAGS) $(srcdir)/mi/mi-parse.c
+
+#
+# nindy-share sub-directory
+#
+# Need to explicitly specify the compile rule as make will do nothing
+# or try to compile the object file into the mi directory.
+
+Onindy.o: nindy-share/Onindy.c $(gdb_wait_h) nindy-share/block_io.h \
+       nindy-share/env.h
+       $(CC) -c $(INTERNAL_CFLAGS) $(srcdir)/nindy-share/Onindy.c
+
+nindy.o: nindy-share/nindy.c $(gdb_wait_h) nindy-share/block_io.h \
+       nindy-share/env.h
+       $(CC) -c $(INTERNAL_CFLAGS) $(srcdir)/nindy-share/nindy.c
+
+ttyflush.o: nindy-share/ttyflush.c $(srcdir)/nindy-share/ttyflush.c
+       $(CC) -c $(INTERNAL_CFLAGS) $(srcdir)/nindy-share/ttyflush.c
+
+#
+# rdi-share sub-directory
+#
+# Need to explicitly specify the compile rule as make will do nothing
+# or try to compile the object file into the mi directory.
+
+rdi-share/libangsd.a:  force
+       @dir=rdi-share; \
+       if [ -f ./$${dir}/Makefile ] ; then \
+         r=`pwd`; export r; \
+         srcroot=`cd $(srcdir); pwd`; export srcroot; \
+         (cd $${dir}; $(MAKE) $(FLAGS_TO_PASS) all); \
+       else \
+         true; \
+       fi
+
+#
+# Signals sub-directory
+#
+# Need to explicitly specify the compile rule as make will do nothing
+# or try to compile the object file into the mi directory.
+
+signals.o: $(srcdir)/signals/signals.c $(defs_h) $(target_h) $(gdb_string_h)
+       $(CC) -c $(INTERNAL_CFLAGS) $(srcdir)/signals/signals.c
+
+#
+# TUI dependencies
+#
+# Need to explicitly specify the compile rule as make will do nothing
+# or try to compile the object file into the mi directory.
+
+tui-file.o: $(srcdir)/tui/tui-file.c $(defs_h) $(ui_file_h) $(tui_file_h) \
+       $(tui_tuiIO_h) $(tui_h)
+       $(CC) -c $(INTERNAL_CFLAGS) $(srcdir)/tui/tui-file.c
+tui-hooks.o: $(srcdir)/tui/tui-hooks.c $(config_h) $(defs_h) $(symtab_h) \
+       $(inferior_h) $(command_h) $(bfd_h) $(symfile_h) $(objfiles_h) \
+       $(target_h) $(gdbcore_h) $(event_loop_h) $(frame_h) $(breakpoint_h) \
+       $(gdb_events_h) $(tui_h) $(tuiData_h) $(tuiLayout_h) $(tuiIO_h) \
+       $(tuiRegs_h) $(tuiWin_h) $(tuiStack_h) $(tuiDataWin_h) \
+       $(tuiSourceWin_h)
+       $(CC) -c $(INTERNAL_CFLAGS) $(srcdir)/tui/tui-hooks.c
+tui-out.o: $(srcdir)/tui/tui-out.c $(defs_h) $(ui_out_h) $(tui_h) \
+       $(gdb_string_h) $(gdb_assert_h)
+       $(CC) -c $(INTERNAL_CFLAGS) $(srcdir)/tui/tui-out.c
+tui.o: $(srcdir)/tui/tui.c $(config_h) $(defs_h) $(gdbcmd_h) $(tui_h) \
+       $(tuiData_h) $(tuiLayout_h) $(tuiIO_h) $(tuiRegs_h) $(tuiStack_h) \
+       $(tuiWin_h) $(tuiSourceWin_h) $(readline_h) $(target_h) $(frame_h) \
+       $(breakpoint_h) $(inferior_h)
+       $(CC) -c $(INTERNAL_CFLAGS) $(srcdir)/tui/tui.c
+tuiCommand.o: $(srcdir)/tui/tuiCommand.c $(config_h) $(defs_h) $(tui_h) \
+       $(tuiData_h) $(tuiWin_h) $(tuiIO_h)
+       $(CC) -c $(INTERNAL_CFLAGS) $(srcdir)/tui/tuiCommand.c
+tuiData.o: $(srcdir)/tui/tuiData.c $(config_h) $(defs_h) $(tui_h) \
+       $(tuiData_h) $(tuiGeneralWin_h)
+       $(CC) -c $(INTERNAL_CFLAGS) $(srcdir)/tui/tuiData.c
+tuiDataWin.o: $(srcdir)/tui/tuiDataWin.c $(config_h) $(defs_h) $(tui_h) \
+       $(tuiData_h) $(tuiGeneralWin_h) $(tuiRegs_h)
+       $(CC) -c $(INTERNAL_CFLAGS) $(srcdir)/tui/tuiDataWin.c
+tuiDisassem.o: $(srcdir)/tui/tuiDisassem.c $(config_h) $(defs_h) $(symtab_h) \
+       $(breakpoint_h) $(frame_h) $(value_h) $(tui_h) $(tuiData_h) \
+       $(tuiWin_h) $(tuiLayout_h) $(tuiSourceWin_h) $(tuiStack_h) \
+       $(tui_file_h)
+       $(CC) -c $(INTERNAL_CFLAGS) $(srcdir)/tui/tuiDisassem.c
+tuiGeneralWin.o: $(srcdir)/tui/tuiGeneralWin.c $(config_h) $(defs_h) \
+       $(tui_h) $(tuiData_h) $(tuiGeneralWin_h) $(tuiWin_h)
+       $(CC) -c $(INTERNAL_CFLAGS) $(srcdir)/tui/tuiGeneralWin.c
+tuiIO.o: $(srcdir)/tui/tuiIO.c $(config_h) $(defs_h) $(terminal_h) \
+       $(target_h) $(event_loop_h) $(command_h) $(top_h) $(readline_h) \
+       $(tui_h) $(tuiData_h) $(tuiIO_h) $(tuiCommand_h) $(tuiWin_h) \
+       $(tuiGeneralWin_h) $(tui_file_h) $(ui_out_h) $(cli_out_h)
+       $(CC) -c $(INTERNAL_CFLAGS) $(srcdir)/tui/tuiIO.c
+tuiLayout.o: $(srcdir)/tui/tuiLayout.c $(config_h) $(defs_h) $(command_h) \
+       $(symtab_h) $(frame_h) $(tui_h) $(tuiData_h) $(tuiDataWin_h) \
+       $(tuiGeneralWin_h) $(tuiStack_h) $(tuiRegs_h) $(tuiWin_h) \
+       $(tuiSourceWin_h) $(tuiDisassem_h)
+       $(CC) -c $(INTERNAL_CFLAGS) $(srcdir)/tui/tuiLayout.c
+tuiRegs.o: $(srcdir)/tui/tuiRegs.c $(config_h) $(defs_h) $(tui_h) \
+       $(tuiData_h) $(symtab_h) $(gdbtypes_h) $(gdbcmd_h) $(frame_h) \
+       $(inferior_h) $(target_h) $(tuiLayout_h) $(tuiWin_h) $(tuiDataWin_h) \
+       $(tuiGeneralWin_h) $(tui_file_h)
+       $(CC) -c $(INTERNAL_CFLAGS) $(srcdir)/tui/tuiRegs.c
+tuiSource.o: $(srcdir)/tui/tuiSource.c $(config_h) $(defs_h) $(symtab_h) \
+       $(frame_h) $(breakpoint_h) $(source_h) $(symtab_h) $(tui_h) \
+       $(tuiData_h) $(tuiStack_h) $(tuiSourceWin_h) $(tuiSource_h)
+       $(CC) -c $(INTERNAL_CFLAGS) $(srcdir)/tui/tuiSource.c
+tuiSourceWin.o: $(srcdir)/tui/tuiSourceWin.c $(config_h) $(defs_h) \
+       $(symtab_h) $(frame_h) $(breakpoint_h) $(value_h) $(tui_h) \
+       $(tuiData_h) $(tuiStack_h) $(tuiWin_h) $(tuiGeneralWin_h) \
+       $(tuiSourceWin_h) $(tuiSource_h) $(tuiDisassem_h)
+       $(CC) -c $(INTERNAL_CFLAGS) $(srcdir)/tui/tuiSourceWin.c
+tuiStack.o: $(srcdir)/tui/tuiStack.c $(config_h) $(defs_h) $(symtab_h) \
+       $(breakpoint_h) $(frame_h) $(command_h) $(tui_h) $(tuiData_h) \
+       $(tuiStack_h) $(tuiGeneralWin_h) $(tuiSource_h) $(tuiSourceWin_h)
+       $(CC) -c $(INTERNAL_CFLAGS) $(srcdir)/tui/tuiStack.c
+tuiWin.o: $(srcdir)/tui/tuiWin.c $(config_h) $(defs_h) $(command_h) \
+       $(symtab_h) $(breakpoint_h) $(frame_h) $(cli_cmds_h) $(tui_h) \
+       $(tuiData_h) $(tuiGeneralWin_h) $(tuiStack_h) $(tuiRegs_h) \
+       $(tuiDisassem_h) $(tuiSource_h) $(tuiSourceWin_h) $(tuiDataWin_h)
+       $(CC) -c $(INTERNAL_CFLAGS) $(srcdir)/tui/tuiWin.c
+
+#
+# vx-share sub-directory
+#
+
+xdr_ld.o: vx-share/xdr_ld.c $(defs_h) vx-share/vxTypes.h \
+       vx-share/vxWorks.h vx-share/xdr_ld.h
+       $(CC) -c $(INTERNAL_CFLAGS) $(srcdir)/vx-share/xdr_ld.c
+
+xdr_ptrace.o: vx-share/xdr_ptrace.c $(defs_h) vx-share/vxTypes.h \
+       vx-share/vxWorks.h vx-share/xdr_ptrace.h
+       $(CC) -c $(INTERNAL_CFLAGS) $(srcdir)/vx-share/xdr_ptrace.c
+
+xdr_rdb.o: vx-share/xdr_rdb.c $(defs_h) vx-share/vxTypes.h \
+       vx-share/vxWorks.h vx-share/xdr_rdb.h
+       $(CC) -c $(INTERNAL_CFLAGS) $(srcdir)/vx-share/xdr_rdb.c
+
+charset.o: charset.c $(defs_h) $(charset_h) $(gdbcmd_h) gdb_assert.h
+
+c-lang.o: $(charset_h)
+utils.o: $(charset_h)
+### end of the gdb Makefile.in.
diff --git a/gdb/ada-lang.c b/gdb/ada-lang.c
new file mode 100644 (file)
index 0000000..2838df7
--- /dev/null
@@ -0,0 +1,8311 @@
+/* Ada language support routines for GDB, the GNU debugger.  Copyright
+   1992, 1993, 1994, 1997, 1998, 1999, 2000 Free Software Foundation, Inc.
+
+This file is part of GDB.
+
+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., 675 Mass Ave, Cambridge, MA 02139, USA.  */
+
+#include <stdio.h>
+#include "gdb_string.h"
+#include <ctype.h>
+#include <stdarg.h>
+#include "demangle.h"
+#include "defs.h"
+#include "symtab.h"
+#include "gdbtypes.h"
+#include "gdbcmd.h"
+#include "expression.h"
+#include "parser-defs.h"
+#include "language.h"
+#include "c-lang.h"
+#include "inferior.h"
+#include "symfile.h"
+#include "objfiles.h"
+#include "breakpoint.h"
+#include "gdbcore.h"
+#include "ada-lang.h"
+#ifdef UI_OUT
+#include "ui-out.h"
+#endif
+
+struct cleanup *unresolved_names;
+
+void extract_string (CORE_ADDR addr, char *buf);
+
+static struct type *ada_create_fundamental_type (struct objfile *, int);
+
+static void modify_general_field (char *, LONGEST, int, int);
+
+static struct type *desc_base_type (struct type *);
+
+static struct type *desc_bounds_type (struct type *);
+
+static struct value *desc_bounds (struct value *);
+
+static int fat_pntr_bounds_bitpos (struct type *);
+
+static int fat_pntr_bounds_bitsize (struct type *);
+
+static struct type *desc_data_type (struct type *);
+
+static struct value *desc_data (struct value *);
+
+static int fat_pntr_data_bitpos (struct type *);
+
+static int fat_pntr_data_bitsize (struct type *);
+
+static struct value *desc_one_bound (struct value *, int, int);
+
+static int desc_bound_bitpos (struct type *, int, int);
+
+static int desc_bound_bitsize (struct type *, int, int);
+
+static struct type *desc_index_type (struct type *, int);
+
+static int desc_arity (struct type *);
+
+static int ada_type_match (struct type *, struct type *, int);
+
+static int ada_args_match (struct symbol *, struct value **, int);
+
+static struct value *place_on_stack (struct value *, CORE_ADDR *);
+
+static struct value *convert_actual (struct value *, struct type *,
+                                    CORE_ADDR *);
+
+static struct value *make_array_descriptor (struct type *, struct value *,
+                                           CORE_ADDR *);
+
+static void ada_add_block_symbols (struct block *, const char *,
+                                  namespace_enum, struct objfile *, int);
+
+static void fill_in_ada_prototype (struct symbol *);
+
+static int is_nonfunction (struct symbol **, int);
+
+static void add_defn_to_vec (struct symbol *, struct block *);
+
+static struct partial_symbol *ada_lookup_partial_symbol (struct partial_symtab
+                                                        *, const char *, int,
+                                                        namespace_enum, int);
+
+static struct symtab *symtab_for_sym (struct symbol *);
+
+static struct value *ada_resolve_subexp (struct expression **, int *, int,
+                                        struct type *);
+
+static void replace_operator_with_call (struct expression **, int, int, int,
+                                       struct symbol *, struct block *);
+
+static int possible_user_operator_p (enum exp_opcode, struct value **);
+
+static const char *ada_op_name (enum exp_opcode);
+
+static int numeric_type_p (struct type *);
+
+static int integer_type_p (struct type *);
+
+static int scalar_type_p (struct type *);
+
+static int discrete_type_p (struct type *);
+
+static char *extended_canonical_line_spec (struct symtab_and_line,
+                                          const char *);
+
+static struct value *evaluate_subexp (struct type *, struct expression *,
+                                     int *, enum noside);
+
+static struct value *evaluate_subexp_type (struct expression *, int *);
+
+static struct type *ada_create_fundamental_type (struct objfile *, int);
+
+static int is_dynamic_field (struct type *, int);
+
+static struct type *to_fixed_variant_branch_type (struct type *, char *,
+                                                 CORE_ADDR, struct value *);
+
+static struct type *to_fixed_range_type (char *, struct value *,
+                                        struct objfile *);
+
+static struct type *to_static_fixed_type (struct type *);
+
+static struct value *unwrap_value (struct value *);
+
+static struct type *packed_array_type (struct type *, long *);
+
+static struct type *decode_packed_array_type (struct type *);
+
+static struct value *decode_packed_array (struct value *);
+
+static struct value *value_subscript_packed (struct value *, int,
+                                            struct value **);
+
+static struct value *coerce_unspec_val_to_type (struct value *, long,
+                                               struct type *);
+
+static struct value *get_var_value (char *, char *);
+
+static int lesseq_defined_than (struct symbol *, struct symbol *);
+
+static int equiv_types (struct type *, struct type *);
+
+static int is_name_suffix (const char *);
+
+static int wild_match (const char *, int, const char *);
+
+static struct symtabs_and_lines find_sal_from_funcs_and_line (const char *,
+                                                             int,
+                                                             struct symbol
+                                                             **, int);
+
+static int find_line_in_linetable (struct linetable *, int, struct symbol **,
+                                  int, int *);
+
+static int find_next_line_in_linetable (struct linetable *, int, int, int);
+
+static struct symtabs_and_lines all_sals_for_line (const char *, int,
+                                                  char ***);
+
+static void read_all_symtabs (const char *);
+
+static int is_plausible_func_for_line (struct symbol *, int);
+
+static struct value *ada_coerce_ref (struct value *);
+
+static struct value *value_pos_atr (struct value *);
+
+static struct value *value_val_atr (struct type *, struct value *);
+
+static struct symbol *standard_lookup (const char *, namespace_enum);
+
+extern void markTimeStart (int index);
+extern void markTimeStop (int index);
+\f
+
+
+/* Maximum-sized dynamic type. */
+static unsigned int varsize_limit;
+
+static const char *ada_completer_word_break_characters =
+  " \t\n!@#$%^&*()+=|~`}{[]\";:?/,-";
+
+/* The name of the symbol to use to get the name of the main subprogram */
+#define ADA_MAIN_PROGRAM_SYMBOL_NAME "__gnat_ada_main_program_name"
+
+                               /* Utilities */
+
+/* extract_string
+ *
+ * read the string located at ADDR from the inferior and store the
+ * result into BUF
+ */
+void
+extract_string (CORE_ADDR addr, char *buf)
+{
+  int char_index = 0;
+
+  /* Loop, reading one byte at a time, until we reach the '\000' 
+     end-of-string marker */
+  do
+    {
+      target_read_memory (addr + char_index * sizeof (char),
+                         buf + char_index * sizeof (char), sizeof (char));
+      char_index++;
+    }
+  while (buf[char_index - 1] != '\000');
+}
+
+/* Assuming *OLD_VECT points to an array of *SIZE objects of size
+   ELEMENT_SIZE, grow it to contain at least MIN_SIZE objects,
+   updating *OLD_VECT and *SIZE as necessary. */
+
+void
+grow_vect (void **old_vect, size_t * size, size_t min_size, int element_size)
+{
+  if (*size < min_size)
+    {
+      *size *= 2;
+      if (*size < min_size)
+       *size = min_size;
+      *old_vect = xrealloc (*old_vect, *size * element_size);
+    }
+}
+
+/* True (non-zero) iff TARGET matches FIELD_NAME up to any trailing
+   suffix of FIELD_NAME beginning "___" */
+
+static int
+field_name_match (const char *field_name, const char *target)
+{
+  int len = strlen (target);
+  return
+    STREQN (field_name, target, len)
+    && (field_name[len] == '\0'
+       || (STREQN (field_name + len, "___", 3)
+           && !STREQ (field_name + strlen (field_name) - 6, "___XVN")));
+}
+
+
+/* The length of the prefix of NAME prior to any "___" suffix. */
+
+int
+ada_name_prefix_len (const char *name)
+{
+  if (name == NULL)
+    return 0;
+  else
+    {
+      const char *p = strstr (name, "___");
+      if (p == NULL)
+       return strlen (name);
+      else
+       return p - name;
+    }
+}
+
+/* SUFFIX is a suffix of STR. False if STR is null. */
+static int
+is_suffix (const char *str, const char *suffix)
+{
+  int len1, len2;
+  if (str == NULL)
+    return 0;
+  len1 = strlen (str);
+  len2 = strlen (suffix);
+  return (len1 >= len2 && STREQ (str + len1 - len2, suffix));
+}
+
+/* Create a value of type TYPE whose contents come from VALADDR, if it
+ * is non-null, and whose memory address (in the inferior) is
+ * ADDRESS. */
+struct value *
+value_from_contents_and_address (struct type *type, char *valaddr,
+                                CORE_ADDR address)
+{
+  struct value *v = allocate_value (type);
+  if (valaddr == NULL)
+    VALUE_LAZY (v) = 1;
+  else
+    memcpy (VALUE_CONTENTS_RAW (v), valaddr, TYPE_LENGTH (type));
+  VALUE_ADDRESS (v) = address;
+  if (address != 0)
+    VALUE_LVAL (v) = lval_memory;
+  return v;
+}
+
+/* The contents of value VAL, beginning at offset OFFSET, treated as a
+   value of type TYPE.  The result is an lval in memory if VAL is. */
+
+static struct value *
+coerce_unspec_val_to_type (struct value *val, long offset, struct type *type)
+{
+  CHECK_TYPEDEF (type);
+  if (VALUE_LVAL (val) == lval_memory)
+    return value_at_lazy (type,
+                         VALUE_ADDRESS (val) + VALUE_OFFSET (val) + offset,
+                         NULL);
+  else
+    {
+      struct value *result = allocate_value (type);
+      VALUE_LVAL (result) = not_lval;
+      if (VALUE_ADDRESS (val) == 0)
+       memcpy (VALUE_CONTENTS_RAW (result), VALUE_CONTENTS (val) + offset,
+               TYPE_LENGTH (type) > TYPE_LENGTH (VALUE_TYPE (val))
+               ? TYPE_LENGTH (VALUE_TYPE (val)) : TYPE_LENGTH (type));
+      else
+       {
+         VALUE_ADDRESS (result) =
+           VALUE_ADDRESS (val) + VALUE_OFFSET (val) + offset;
+         VALUE_LAZY (result) = 1;
+       }
+      return result;
+    }
+}
+
+static char *
+cond_offset_host (char *valaddr, long offset)
+{
+  if (valaddr == NULL)
+    return NULL;
+  else
+    return valaddr + offset;
+}
+
+static CORE_ADDR
+cond_offset_target (CORE_ADDR address, long offset)
+{
+  if (address == 0)
+    return 0;
+  else
+    return address + offset;
+}
+
+/* Perform execute_command on the result of concatenating all
+   arguments up to NULL. */
+static void
+do_command (const char *arg, ...)
+{
+  int len;
+  char *cmd;
+  const char *s;
+  va_list ap;
+
+  va_start (ap, arg);
+  len = 0;
+  s = arg;
+  cmd = "";
+  for (; s != NULL; s = va_arg (ap, const char *))
+    {
+      char *cmd1;
+      len += strlen (s);
+      cmd1 = alloca (len + 1);
+      strcpy (cmd1, cmd);
+      strcat (cmd1, s);
+      cmd = cmd1;
+    }
+  va_end (ap);
+  execute_command (cmd, 0);
+}
+\f
+
+                               /* Language Selection */
+
+/* If the main program is in Ada, return language_ada, otherwise return LANG
+   (the main program is in Ada iif the adainit symbol is found).
+
+   MAIN_PST is not used. */
+
+enum language
+ada_update_initial_language (enum language lang,
+                            struct partial_symtab *main_pst)
+{
+  if (lookup_minimal_symbol ("adainit", (const char *) NULL,
+                            (struct objfile *) NULL) != NULL)
+    /*    return language_ada; */
+    /* FIXME: language_ada should be defined in defs.h */
+    return language_unknown;
+
+  return lang;
+}
+\f
+
+                               /* Symbols */
+
+/* Table of Ada operators and their GNAT-mangled names.  Last entry is pair 
+   of NULLs. */
+
+const struct ada_opname_map ada_opname_table[] = {
+  {"Oadd", "\"+\"", BINOP_ADD},
+  {"Osubtract", "\"-\"", BINOP_SUB},
+  {"Omultiply", "\"*\"", BINOP_MUL},
+  {"Odivide", "\"/\"", BINOP_DIV},
+  {"Omod", "\"mod\"", BINOP_MOD},
+  {"Orem", "\"rem\"", BINOP_REM},
+  {"Oexpon", "\"**\"", BINOP_EXP},
+  {"Olt", "\"<\"", BINOP_LESS},
+  {"Ole", "\"<=\"", BINOP_LEQ},
+  {"Ogt", "\">\"", BINOP_GTR},
+  {"Oge", "\">=\"", BINOP_GEQ},
+  {"Oeq", "\"=\"", BINOP_EQUAL},
+  {"One", "\"/=\"", BINOP_NOTEQUAL},
+  {"Oand", "\"and\"", BINOP_BITWISE_AND},
+  {"Oor", "\"or\"", BINOP_BITWISE_IOR},
+  {"Oxor", "\"xor\"", BINOP_BITWISE_XOR},
+  {"Oconcat", "\"&\"", BINOP_CONCAT},
+  {"Oabs", "\"abs\"", UNOP_ABS},
+  {"Onot", "\"not\"", UNOP_LOGICAL_NOT},
+  {"Oadd", "\"+\"", UNOP_PLUS},
+  {"Osubtract", "\"-\"", UNOP_NEG},
+  {NULL, NULL}
+};
+
+/* True if STR should be suppressed in info listings. */
+static int
+is_suppressed_name (const char *str)
+{
+  if (STREQN (str, "_ada_", 5))
+    str += 5;
+  if (str[0] == '_' || str[0] == '\000')
+    return 1;
+  else
+    {
+      const char *p;
+      const char *suffix = strstr (str, "___");
+      if (suffix != NULL && suffix[3] != 'X')
+       return 1;
+      if (suffix == NULL)
+       suffix = str + strlen (str);
+      for (p = suffix - 1; p != str; p -= 1)
+       if (isupper (*p))
+         {
+           int i;
+           if (p[0] == 'X' && p[-1] != '_')
+             goto OK;
+           if (*p != 'O')
+             return 1;
+           for (i = 0; ada_opname_table[i].mangled != NULL; i += 1)
+             if (STREQN (ada_opname_table[i].mangled, p,
+                         strlen (ada_opname_table[i].mangled)))
+               goto OK;
+           return 1;
+         OK:;
+         }
+      return 0;
+    }
+}
+
+/* The "mangled" form of DEMANGLED, according to GNAT conventions.
+ * The result is valid until the next call to ada_mangle. */
+char *
+ada_mangle (const char *demangled)
+{
+  static char *mangling_buffer = NULL;
+  static size_t mangling_buffer_size = 0;
+  const char *p;
+  int k;
+
+  if (demangled == NULL)
+    return NULL;
+
+  GROW_VECT (mangling_buffer, mangling_buffer_size,
+            2 * strlen (demangled) + 10);
+
+  k = 0;
+  for (p = demangled; *p != '\0'; p += 1)
+    {
+      if (*p == '.')
+       {
+         mangling_buffer[k] = mangling_buffer[k + 1] = '_';
+         k += 2;
+       }
+      else if (*p == '"')
+       {
+         const struct ada_opname_map *mapping;
+
+         for (mapping = ada_opname_table;
+              mapping->mangled != NULL &&
+              !STREQN (mapping->demangled, p, strlen (mapping->demangled));
+              p += 1)
+           ;
+         if (mapping->mangled == NULL)
+           error ("invalid Ada operator name: %s", p);
+         strcpy (mangling_buffer + k, mapping->mangled);
+         k += strlen (mapping->mangled);
+         break;
+       }
+      else
+       {
+         mangling_buffer[k] = *p;
+         k += 1;
+       }
+    }
+
+  mangling_buffer[k] = '\0';
+  return mangling_buffer;
+}
+
+/* Return NAME folded to lower case, or, if surrounded by single
+ * quotes, unfolded, but with the quotes stripped away.  Result good
+ * to next call. */
+char *
+ada_fold_name (const char *name)
+{
+  static char *fold_buffer = NULL;
+  static size_t fold_buffer_size = 0;
+
+  int len = strlen (name);
+  GROW_VECT (fold_buffer, fold_buffer_size, len + 1);
+
+  if (name[0] == '\'')
+    {
+      strncpy (fold_buffer, name + 1, len - 2);
+      fold_buffer[len - 2] = '\000';
+    }
+  else
+    {
+      int i;
+      for (i = 0; i <= len; i += 1)
+       fold_buffer[i] = tolower (name[i]);
+    }
+
+  return fold_buffer;
+}
+
+/* Demangle: 
+     1. Discard final __{DIGIT}+ or ${DIGIT}+
+     2. Convert other instances of embedded "__" to `.'.
+     3. Discard leading _ada_.
+     4. Convert operator names to the appropriate quoted symbols.
+     5. Remove everything after first ___ if it is followed by 
+        'X'.
+     6. Replace TK__ with __, and a trailing B or TKB with nothing.
+     7. Put symbols that should be suppressed in <...> brackets.
+     8. Remove trailing X[bn]* suffix (indicating names in package bodies).
+   The resulting string is valid until the next call of ada_demangle.
+  */
+
+char *
+ada_demangle (const char *mangled)
+{
+  int i, j;
+  int len0;
+  const char *p;
+  char *demangled;
+  int at_start_name;
+  static char *demangling_buffer = NULL;
+  static size_t demangling_buffer_size = 0;
+
+  if (STREQN (mangled, "_ada_", 5))
+    mangled += 5;
+
+  if (mangled[0] == '_' || mangled[0] == '<')
+    goto Suppress;
+
+  p = strstr (mangled, "___");
+  if (p == NULL)
+    len0 = strlen (mangled);
+  else
+    {
+      if (p[3] == 'X')
+       len0 = p - mangled;
+      else
+       goto Suppress;
+    }
+  if (len0 > 3 && STREQ (mangled + len0 - 3, "TKB"))
+    len0 -= 3;
+  if (len0 > 1 && STREQ (mangled + len0 - 1, "B"))
+    len0 -= 1;
+
+  /* Make demangled big enough for possible expansion by operator name. */
+  GROW_VECT (demangling_buffer, demangling_buffer_size, 2 * len0 + 1);
+  demangled = demangling_buffer;
+
+  if (isdigit (mangled[len0 - 1]))
+    {
+      for (i = len0 - 2; i >= 0 && isdigit (mangled[i]); i -= 1)
+       ;
+      if (i > 1 && mangled[i] == '_' && mangled[i - 1] == '_')
+       len0 = i - 1;
+      else if (mangled[i] == '$')
+       len0 = i;
+    }
+
+  for (i = 0, j = 0; i < len0 && !isalpha (mangled[i]); i += 1, j += 1)
+    demangled[j] = mangled[i];
+
+  at_start_name = 1;
+  while (i < len0)
+    {
+      if (at_start_name && mangled[i] == 'O')
+       {
+         int k;
+         for (k = 0; ada_opname_table[k].mangled != NULL; k += 1)
+           {
+             int op_len = strlen (ada_opname_table[k].mangled);
+             if (STREQN
+                 (ada_opname_table[k].mangled + 1, mangled + i + 1,
+                  op_len - 1) && !isalnum (mangled[i + op_len]))
+               {
+                 strcpy (demangled + j, ada_opname_table[k].demangled);
+                 at_start_name = 0;
+                 i += op_len;
+                 j += strlen (ada_opname_table[k].demangled);
+                 break;
+               }
+           }
+         if (ada_opname_table[k].mangled != NULL)
+           continue;
+       }
+      at_start_name = 0;
+
+      if (i < len0 - 4 && STREQN (mangled + i, "TK__", 4))
+       i += 2;
+      if (mangled[i] == 'X' && i != 0 && isalnum (mangled[i - 1]))
+       {
+         do
+           i += 1;
+         while (i < len0 && (mangled[i] == 'b' || mangled[i] == 'n'));
+         if (i < len0)
+           goto Suppress;
+       }
+      else if (i < len0 - 2 && mangled[i] == '_' && mangled[i + 1] == '_')
+       {
+         demangled[j] = '.';
+         at_start_name = 1;
+         i += 2;
+         j += 1;
+       }
+      else
+       {
+         demangled[j] = mangled[i];
+         i += 1;
+         j += 1;
+       }
+    }
+  demangled[j] = '\000';
+
+  for (i = 0; demangled[i] != '\0'; i += 1)
+    if (isupper (demangled[i]) || demangled[i] == ' ')
+      goto Suppress;
+
+  return demangled;
+
+Suppress:
+  GROW_VECT (demangling_buffer, demangling_buffer_size, strlen (mangled) + 3);
+  demangled = demangling_buffer;
+  if (mangled[0] == '<')
+    strcpy (demangled, mangled);
+  else
+    sprintf (demangled, "<%s>", mangled);
+  return demangled;
+
+}
+
+/* Returns non-zero iff SYM_NAME matches NAME, ignoring any trailing
+ * suffixes that encode debugging information or leading _ada_ on
+ * SYM_NAME (see is_name_suffix commentary for the debugging
+ * information that is ignored).  If WILD, then NAME need only match a
+ * suffix of SYM_NAME minus the same suffixes. Also returns 0 if
+ * either argument is NULL. */
+
+int
+ada_match_name (const char *sym_name, const char *name, int wild)
+{
+  if (sym_name == NULL || name == NULL)
+    return 0;
+  else if (wild)
+    return wild_match (name, strlen (name), sym_name);
+  else
+    {
+      int len_name = strlen (name);
+      return (STREQN (sym_name, name, len_name)
+             && is_name_suffix (sym_name + len_name))
+       || (STREQN (sym_name, "_ada_", 5)
+           && STREQN (sym_name + 5, name, len_name)
+           && is_name_suffix (sym_name + len_name + 5));
+    }
+}
+
+/* True (non-zero) iff in Ada mode, the symbol SYM should be
+   suppressed in info listings. */
+
+int
+ada_suppress_symbol_printing (struct symbol *sym)
+{
+  if (SYMBOL_NAMESPACE (sym) == STRUCT_NAMESPACE)
+    return 1;
+  else
+    return is_suppressed_name (SYMBOL_NAME (sym));
+}
+\f
+
+                               /* Arrays */
+
+/* Names of MAX_ADA_DIMENS bounds in P_BOUNDS fields of 
+   array descriptors.  */
+
+static char *bound_name[] = {
+  "LB0", "UB0", "LB1", "UB1", "LB2", "UB2", "LB3", "UB3",
+  "LB4", "UB4", "LB5", "UB5", "LB6", "UB6", "LB7", "UB7"
+};
+
+/* Maximum number of array dimensions we are prepared to handle.  */
+
+#define MAX_ADA_DIMENS (sizeof(bound_name) / (2*sizeof(char*)))
+
+/* Like modify_field, but allows bitpos > wordlength. */
+
+static void
+modify_general_field (char *addr, LONGEST fieldval, int bitpos, int bitsize)
+{
+  modify_field (addr + sizeof (LONGEST) * bitpos / (8 * sizeof (LONGEST)),
+               fieldval, bitpos % (8 * sizeof (LONGEST)), bitsize);
+}
+
+
+/* The desc_* routines return primitive portions of array descriptors 
+   (fat pointers). */
+
+/* The descriptor or array type, if any, indicated by TYPE; removes
+   level of indirection, if needed. */
+static struct type *
+desc_base_type (struct type *type)
+{
+  if (type == NULL)
+    return NULL;
+  CHECK_TYPEDEF (type);
+  if (type != NULL && TYPE_CODE (type) == TYPE_CODE_PTR)
+    return check_typedef (TYPE_TARGET_TYPE (type));
+  else
+    return type;
+}
+
+/* True iff TYPE indicates a "thin" array pointer type. */
+static int
+is_thin_pntr (struct type *type)
+{
+  return
+    is_suffix (ada_type_name (desc_base_type (type)), "___XUT")
+    || is_suffix (ada_type_name (desc_base_type (type)), "___XUT___XVE");
+}
+
+/* The descriptor type for thin pointer type TYPE. */
+static struct type *
+thin_descriptor_type (struct type *type)
+{
+  struct type *base_type = desc_base_type (type);
+  if (base_type == NULL)
+    return NULL;
+  if (is_suffix (ada_type_name (base_type), "___XVE"))
+    return base_type;
+  else
+    {
+      struct type *alt_type = ada_find_parallel_type (base_type, "___XVE");
+      if (alt_type == NULL)
+       return base_type;
+      else
+       return alt_type;
+    }
+}
+
+/* A pointer to the array data for thin-pointer value VAL. */
+static struct value *
+thin_data_pntr (struct value *val)
+{
+  struct type *type = VALUE_TYPE (val);
+  if (TYPE_CODE (type) == TYPE_CODE_PTR)
+    return value_cast (desc_data_type (thin_descriptor_type (type)),
+                      value_copy (val));
+  else
+    return value_from_longest (desc_data_type (thin_descriptor_type (type)),
+                              VALUE_ADDRESS (val) + VALUE_OFFSET (val));
+}
+
+/* True iff TYPE indicates a "thick" array pointer type. */
+static int
+is_thick_pntr (struct type *type)
+{
+  type = desc_base_type (type);
+  return (type != NULL && TYPE_CODE (type) == TYPE_CODE_STRUCT
+         && lookup_struct_elt_type (type, "P_BOUNDS", 1) != NULL);
+}
+
+/* If TYPE is the type of an array descriptor (fat or thin pointer) or a 
+   pointer to one, the type of its bounds data; otherwise, NULL. */
+static struct type *
+desc_bounds_type (struct type *type)
+{
+  struct type *r;
+
+  type = desc_base_type (type);
+
+  if (type == NULL)
+    return NULL;
+  else if (is_thin_pntr (type))
+    {
+      type = thin_descriptor_type (type);
+      if (type == NULL)
+       return NULL;
+      r = lookup_struct_elt_type (type, "BOUNDS", 1);
+      if (r != NULL)
+       return check_typedef (r);
+    }
+  else if (TYPE_CODE (type) == TYPE_CODE_STRUCT)
+    {
+      r = lookup_struct_elt_type (type, "P_BOUNDS", 1);
+      if (r != NULL)
+       return check_typedef (TYPE_TARGET_TYPE (check_typedef (r)));
+    }
+  return NULL;
+}
+
+/* If ARR is an array descriptor (fat or thin pointer), or pointer to
+   one, a pointer to its bounds data.   Otherwise NULL. */
+static struct value *
+desc_bounds (struct value *arr)
+{
+  struct type *type = check_typedef (VALUE_TYPE (arr));
+  if (is_thin_pntr (type))
+    {
+      struct type *bounds_type =
+       desc_bounds_type (thin_descriptor_type (type));
+      LONGEST addr;
+
+      if (desc_bounds_type == NULL)
+       error ("Bad GNAT array descriptor");
+
+      /* NOTE: The following calculation is not really kosher, but
+         since desc_type is an XVE-encoded type (and shouldn't be),
+         the correct calculation is a real pain. FIXME (and fix GCC). */
+      if (TYPE_CODE (type) == TYPE_CODE_PTR)
+       addr = value_as_long (arr);
+      else
+       addr = VALUE_ADDRESS (arr) + VALUE_OFFSET (arr);
+
+      return
+       value_from_longest (lookup_pointer_type (bounds_type),
+                           addr - TYPE_LENGTH (bounds_type));
+    }
+
+  else if (is_thick_pntr (type))
+    return value_struct_elt (&arr, NULL, "P_BOUNDS", NULL,
+                            "Bad GNAT array descriptor");
+  else
+    return NULL;
+}
+
+/* If TYPE is the type of an array-descriptor (fat pointer), the bit
+   position of the field containing the address of the bounds data. */
+static int
+fat_pntr_bounds_bitpos (struct type *type)
+{
+  return TYPE_FIELD_BITPOS (desc_base_type (type), 1);
+}
+
+/* If TYPE is the type of an array-descriptor (fat pointer), the bit
+   size of the field containing the address of the bounds data. */
+static int
+fat_pntr_bounds_bitsize (struct type *type)
+{
+  type = desc_base_type (type);
+
+  if (TYPE_FIELD_BITSIZE (type, 1) > 0)
+    return TYPE_FIELD_BITSIZE (type, 1);
+  else
+    return 8 * TYPE_LENGTH (check_typedef (TYPE_FIELD_TYPE (type, 1)));
+}
+
+/* If TYPE is the type of an array descriptor (fat or thin pointer) or a 
+   pointer to one, the type of its array data (a
+   pointer-to-array-with-no-bounds type); otherwise,  NULL.  Use
+   ada_type_of_array to get an array type with bounds data. */
+static struct type *
+desc_data_type (struct type *type)
+{
+  type = desc_base_type (type);
+
+  /* NOTE: The following is bogus; see comment in desc_bounds. */
+  if (is_thin_pntr (type))
+    return lookup_pointer_type
+      (desc_base_type (TYPE_FIELD_TYPE (thin_descriptor_type (type), 1)));
+  else if (is_thick_pntr (type))
+    return lookup_struct_elt_type (type, "P_ARRAY", 1);
+  else
+    return NULL;
+}
+
+/* If ARR is an array descriptor (fat or thin pointer), a pointer to
+   its array data.  */
+static struct value *
+desc_data (struct value *arr)
+{
+  struct type *type = VALUE_TYPE (arr);
+  if (is_thin_pntr (type))
+    return thin_data_pntr (arr);
+  else if (is_thick_pntr (type))
+    return value_struct_elt (&arr, NULL, "P_ARRAY", NULL,
+                            "Bad GNAT array descriptor");
+  else
+    return NULL;
+}
+
+
+/* If TYPE is the type of an array-descriptor (fat pointer), the bit
+   position of the field containing the address of the data. */
+static int
+fat_pntr_data_bitpos (struct type *type)
+{
+  return TYPE_FIELD_BITPOS (desc_base_type (type), 0);
+}
+
+/* If TYPE is the type of an array-descriptor (fat pointer), the bit
+   size of the field containing the address of the data. */
+static int
+fat_pntr_data_bitsize (struct type *type)
+{
+  type = desc_base_type (type);
+
+  if (TYPE_FIELD_BITSIZE (type, 0) > 0)
+    return TYPE_FIELD_BITSIZE (type, 0);
+  else
+    return TARGET_CHAR_BIT * TYPE_LENGTH (TYPE_FIELD_TYPE (type, 0));
+}
+
+/* If BOUNDS is an array-bounds structure (or pointer to one), return 
+   the Ith lower bound stored in it, if WHICH is 0, and the Ith upper
+   bound, if WHICH is 1.  The first bound is I=1. */
+static struct value *
+desc_one_bound (struct value *bounds, int i, int which)
+{
+  return value_struct_elt (&bounds, NULL, bound_name[2 * i + which - 2], NULL,
+                          "Bad GNAT array descriptor bounds");
+}
+
+/* If BOUNDS is an array-bounds structure type, return the bit position
+   of the Ith lower bound stored in it, if WHICH is 0, and the Ith upper
+   bound, if WHICH is 1.  The first bound is I=1. */
+static int
+desc_bound_bitpos (struct type *type, int i, int which)
+{
+  return TYPE_FIELD_BITPOS (desc_base_type (type), 2 * i + which - 2);
+}
+
+/* If BOUNDS is an array-bounds structure type, return the bit field size
+   of the Ith lower bound stored in it, if WHICH is 0, and the Ith upper
+   bound, if WHICH is 1.  The first bound is I=1. */
+static int
+desc_bound_bitsize (struct type *type, int i, int which)
+{
+  type = desc_base_type (type);
+
+  if (TYPE_FIELD_BITSIZE (type, 2 * i + which - 2) > 0)
+    return TYPE_FIELD_BITSIZE (type, 2 * i + which - 2);
+  else
+    return 8 * TYPE_LENGTH (TYPE_FIELD_TYPE (type, 2 * i + which - 2));
+}
+
+/* If TYPE is the type of an array-bounds structure, the type of its
+   Ith bound (numbering from 1). Otherwise, NULL. */
+static struct type *
+desc_index_type (struct type *type, int i)
+{
+  type = desc_base_type (type);
+
+  if (TYPE_CODE (type) == TYPE_CODE_STRUCT)
+    return lookup_struct_elt_type (type, bound_name[2 * i - 2], 1);
+  else
+    return NULL;
+}
+
+/* The number of index positions in the array-bounds type TYPE.  0
+   if TYPE is NULL. */
+static int
+desc_arity (struct type *type)
+{
+  type = desc_base_type (type);
+
+  if (type != NULL)
+    return TYPE_NFIELDS (type) / 2;
+  return 0;
+}
+
+
+/* Non-zero iff type is a simple array type (or pointer to one). */
+int
+ada_is_simple_array (struct type *type)
+{
+  if (type == NULL)
+    return 0;
+  CHECK_TYPEDEF (type);
+  return (TYPE_CODE (type) == TYPE_CODE_ARRAY
+         || (TYPE_CODE (type) == TYPE_CODE_PTR
+             && TYPE_CODE (TYPE_TARGET_TYPE (type)) == TYPE_CODE_ARRAY));
+}
+
+/* Non-zero iff type belongs to a GNAT array descriptor. */
+int
+ada_is_array_descriptor (struct type *type)
+{
+  struct type *data_type = desc_data_type (type);
+
+  if (type == NULL)
+    return 0;
+  CHECK_TYPEDEF (type);
+  return
+    data_type != NULL
+    && ((TYPE_CODE (data_type) == TYPE_CODE_PTR
+        && TYPE_TARGET_TYPE (data_type) != NULL
+        && TYPE_CODE (TYPE_TARGET_TYPE (data_type)) == TYPE_CODE_ARRAY)
+       ||
+       TYPE_CODE (data_type) == TYPE_CODE_ARRAY)
+    && desc_arity (desc_bounds_type (type)) > 0;
+}
+
+/* Non-zero iff type is a partially mal-formed GNAT array
+   descriptor.  (FIXME: This is to compensate for some problems with 
+   debugging output from GNAT.  Re-examine periodically to see if it
+   is still needed. */
+int
+ada_is_bogus_array_descriptor (struct type *type)
+{
+  return
+    type != NULL
+    && TYPE_CODE (type) == TYPE_CODE_STRUCT
+    && (lookup_struct_elt_type (type, "P_BOUNDS", 1) != NULL
+       || lookup_struct_elt_type (type, "P_ARRAY", 1) != NULL)
+    && !ada_is_array_descriptor (type);
+}
+
+
+/* If ARR has a record type in the form of a standard GNAT array descriptor, 
+   (fat pointer) returns the type of the array data described---specifically,
+   a pointer-to-array type.  If BOUNDS is non-zero, the bounds data are filled 
+   in from the descriptor; otherwise, they are left unspecified.  If
+   the ARR denotes a null array descriptor and BOUNDS is non-zero, 
+   returns NULL.  The result is simply the type of ARR if ARR is not 
+   a descriptor.  */
+struct type *
+ada_type_of_array (struct value *arr, int bounds)
+{
+  if (ada_is_packed_array_type (VALUE_TYPE (arr)))
+    return decode_packed_array_type (VALUE_TYPE (arr));
+
+  if (!ada_is_array_descriptor (VALUE_TYPE (arr)))
+    return VALUE_TYPE (arr);
+
+  if (!bounds)
+    return
+      check_typedef (TYPE_TARGET_TYPE (desc_data_type (VALUE_TYPE (arr))));
+  else
+    {
+      struct type *elt_type;
+      int arity;
+      struct value *descriptor;
+      struct objfile *objf = TYPE_OBJFILE (VALUE_TYPE (arr));
+
+      elt_type = ada_array_element_type (VALUE_TYPE (arr), -1);
+      arity = ada_array_arity (VALUE_TYPE (arr));
+
+      if (elt_type == NULL || arity == 0)
+       return check_typedef (VALUE_TYPE (arr));
+
+      descriptor = desc_bounds (arr);
+      if (value_as_long (descriptor) == 0)
+       return NULL;
+      while (arity > 0)
+       {
+         struct type *range_type = alloc_type (objf);
+         struct type *array_type = alloc_type (objf);
+         struct value *low = desc_one_bound (descriptor, arity, 0);
+         struct value *high = desc_one_bound (descriptor, arity, 1);
+         arity -= 1;
+
+         create_range_type (range_type, VALUE_TYPE (low),
+                            (int) value_as_long (low),
+                            (int) value_as_long (high));
+         elt_type = create_array_type (array_type, elt_type, range_type);
+       }
+
+      return lookup_pointer_type (elt_type);
+    }
+}
+
+/* If ARR does not represent an array, returns ARR unchanged.
+   Otherwise, returns either a standard GDB array with bounds set 
+   appropriately or, if ARR is a non-null fat pointer, a pointer to a standard 
+   GDB array.  Returns NULL if ARR is a null fat pointer. */
+struct value *
+ada_coerce_to_simple_array_ptr (struct value *arr)
+{
+  if (ada_is_array_descriptor (VALUE_TYPE (arr)))
+    {
+      struct type *arrType = ada_type_of_array (arr, 1);
+      if (arrType == NULL)
+       return NULL;
+      return value_cast (arrType, value_copy (desc_data (arr)));
+    }
+  else if (ada_is_packed_array_type (VALUE_TYPE (arr)))
+    return decode_packed_array (arr);
+  else
+    return arr;
+}
+
+/* If ARR does not represent an array, returns ARR unchanged.
+   Otherwise, returns a standard GDB array describing ARR (which may
+   be ARR itself if it already is in the proper form). */
+struct value *
+ada_coerce_to_simple_array (struct value *arr)
+{
+  if (ada_is_array_descriptor (VALUE_TYPE (arr)))
+    {
+      struct value *arrVal = ada_coerce_to_simple_array_ptr (arr);
+      if (arrVal == NULL)
+       error ("Bounds unavailable for null array pointer.");
+      return value_ind (arrVal);
+    }
+  else if (ada_is_packed_array_type (VALUE_TYPE (arr)))
+    return decode_packed_array (arr);
+  else
+    return arr;
+}
+
+/* If TYPE represents a GNAT array type, return it translated to an
+   ordinary GDB array type (possibly with BITSIZE fields indicating
+   packing). For other types, is the identity. */
+struct type *
+ada_coerce_to_simple_array_type (struct type *type)
+{
+  struct value *mark = value_mark ();
+  struct value *dummy = value_from_longest (builtin_type_long, 0);
+  struct type *result;
+  VALUE_TYPE (dummy) = type;
+  result = ada_type_of_array (dummy, 0);
+  value_free_to_mark (dummy);
+  return result;
+}
+
+/* Non-zero iff TYPE represents a standard GNAT packed-array type. */
+int
+ada_is_packed_array_type (struct type *type)
+{
+  if (type == NULL)
+    return 0;
+  CHECK_TYPEDEF (type);
+  return
+    ada_type_name (type) != NULL
+    && strstr (ada_type_name (type), "___XP") != NULL;
+}
+
+/* Given that TYPE is a standard GDB array type with all bounds filled
+   in, and that the element size of its ultimate scalar constituents
+   (that is, either its elements, or, if it is an array of arrays, its
+   elements' elements, etc.) is *ELT_BITS, return an identical type,
+   but with the bit sizes of its elements (and those of any
+   constituent arrays) recorded in the BITSIZE components of its
+   TYPE_FIELD_BITSIZE values, and with *ELT_BITS set to its total size 
+   in bits. */
+static struct type *
+packed_array_type (struct type *type, long *elt_bits)
+{
+  struct type *new_elt_type;
+  struct type *new_type;
+  LONGEST low_bound, high_bound;
+
+  CHECK_TYPEDEF (type);
+  if (TYPE_CODE (type) != TYPE_CODE_ARRAY)
+    return type;
+
+  new_type = alloc_type (TYPE_OBJFILE (type));
+  new_elt_type = packed_array_type (check_typedef (TYPE_TARGET_TYPE (type)),
+                                   elt_bits);
+  create_array_type (new_type, new_elt_type, TYPE_FIELD_TYPE (type, 0));
+  TYPE_FIELD_BITSIZE (new_type, 0) = *elt_bits;
+  TYPE_NAME (new_type) = ada_type_name (type);
+
+  if (get_discrete_bounds (TYPE_FIELD_TYPE (type, 0),
+                          &low_bound, &high_bound) < 0)
+    low_bound = high_bound = 0;
+  if (high_bound < low_bound)
+    *elt_bits = TYPE_LENGTH (new_type) = 0;
+  else
+    {
+      *elt_bits *= (high_bound - low_bound + 1);
+      TYPE_LENGTH (new_type) =
+       (*elt_bits + HOST_CHAR_BIT - 1) / HOST_CHAR_BIT;
+    }
+
+  /*  TYPE_FLAGS (new_type) |= TYPE_FLAG_FIXED_INSTANCE; */
+  /* FIXME:  TYPE_FLAG_FIXED_INSTANCE should be defined in gdbtypes.h */
+  return new_type;
+}
+
+/* The array type encoded by TYPE, where ada_is_packed_array_type (TYPE).
+ */
+static struct type *
+decode_packed_array_type (struct type *type)
+{
+  struct symbol **syms;
+  struct block **blocks;
+  const char *raw_name = ada_type_name (check_typedef (type));
+  char *name = (char *) alloca (strlen (raw_name) + 1);
+  char *tail = strstr (raw_name, "___XP");
+  struct type *shadow_type;
+  long bits;
+  int i, n;
+
+  memcpy (name, raw_name, tail - raw_name);
+  name[tail - raw_name] = '\000';
+
+  /* NOTE: Use ada_lookup_symbol_list because of bug in some versions
+   * of gcc (Solaris, e.g.). FIXME when compiler is fixed. */
+  n = ada_lookup_symbol_list (name, get_selected_block (NULL),
+                             VAR_NAMESPACE, &syms, &blocks);
+  for (i = 0; i < n; i += 1)
+    if (syms[i] != NULL && SYMBOL_CLASS (syms[i]) == LOC_TYPEDEF
+       && STREQ (name, ada_type_name (SYMBOL_TYPE (syms[i]))))
+      break;
+  if (i >= n)
+    {
+      warning ("could not find bounds information on packed array");
+      return NULL;
+    }
+  shadow_type = SYMBOL_TYPE (syms[i]);
+
+  if (TYPE_CODE (shadow_type) != TYPE_CODE_ARRAY)
+    {
+      warning ("could not understand bounds information on packed array");
+      return NULL;
+    }
+
+  if (sscanf (tail + sizeof ("___XP") - 1, "%ld", &bits) != 1)
+    {
+      warning ("could not understand bit size information on packed array");
+      return NULL;
+    }
+
+  return packed_array_type (shadow_type, &bits);
+}
+
+/* Given that ARR is a struct value* indicating a GNAT packed array,
+   returns a simple array that denotes that array.  Its type is a
+   standard GDB array type except that the BITSIZEs of the array
+   target types are set to the number of bits in each element, and the
+   type length is set appropriately. */
+
+static struct value *
+decode_packed_array (struct value *arr)
+{
+  struct type *type = decode_packed_array_type (VALUE_TYPE (arr));
+
+  if (type == NULL)
+    {
+      error ("can't unpack array");
+      return NULL;
+    }
+  else
+    return coerce_unspec_val_to_type (arr, 0, type);
+}
+
+
+/* The value of the element of packed array ARR at the ARITY indices
+   given in IND.   ARR must be a simple array. */
+
+static struct value *
+value_subscript_packed (struct value *arr, int arity, struct value **ind)
+{
+  int i;
+  int bits, elt_off, bit_off;
+  long elt_total_bit_offset;
+  struct type *elt_type;
+  struct value *v;
+
+  bits = 0;
+  elt_total_bit_offset = 0;
+  elt_type = check_typedef (VALUE_TYPE (arr));
+  for (i = 0; i < arity; i += 1)
+    {
+      if (TYPE_CODE (elt_type) != TYPE_CODE_ARRAY
+         || TYPE_FIELD_BITSIZE (elt_type, 0) == 0)
+       error
+         ("attempt to do packed indexing of something other than a packed array");
+      else
+       {
+         struct type *range_type = TYPE_INDEX_TYPE (elt_type);
+         LONGEST lowerbound, upperbound;
+         LONGEST idx;
+
+         if (get_discrete_bounds (range_type, &lowerbound, &upperbound) < 0)
+           {
+             warning ("don't know bounds of array");
+             lowerbound = upperbound = 0;
+           }
+
+         idx = value_as_long (value_pos_atr (ind[i]));
+         if (idx < lowerbound || idx > upperbound)
+           warning ("packed array index %ld out of bounds", (long) idx);
+         bits = TYPE_FIELD_BITSIZE (elt_type, 0);
+         elt_total_bit_offset += (idx - lowerbound) * bits;
+         elt_type = check_typedef (TYPE_TARGET_TYPE (elt_type));
+       }
+    }
+  elt_off = elt_total_bit_offset / HOST_CHAR_BIT;
+  bit_off = elt_total_bit_offset % HOST_CHAR_BIT;
+
+  v = ada_value_primitive_packed_val (arr, NULL, elt_off, bit_off,
+                                     bits, elt_type);
+  if (VALUE_LVAL (arr) == lval_internalvar)
+    VALUE_LVAL (v) = lval_internalvar_component;
+  else
+    VALUE_LVAL (v) = VALUE_LVAL (arr);
+  return v;
+}
+
+/* Non-zero iff TYPE includes negative integer values. */
+
+static int
+has_negatives (struct type *type)
+{
+  switch (TYPE_CODE (type))
+    {
+    default:
+      return 0;
+    case TYPE_CODE_INT:
+      return !TYPE_UNSIGNED (type);
+    case TYPE_CODE_RANGE:
+      return TYPE_LOW_BOUND (type) < 0;
+    }
+}
+
+
+/* Create a new value of type TYPE from the contents of OBJ starting
+   at byte OFFSET, and bit offset BIT_OFFSET within that byte,
+   proceeding for BIT_SIZE bits.  If OBJ is an lval in memory, then
+   assigning through the result will set the field fetched from. OBJ
+   may also be NULL, in which case, VALADDR+OFFSET must address the
+   start of storage containing the packed value.  The value returned 
+   in this case is never an lval.   
+   Assumes 0 <= BIT_OFFSET < HOST_CHAR_BIT. */
+
+struct value *
+ada_value_primitive_packed_val (struct value *obj, char *valaddr, long offset,
+                               int bit_offset, int bit_size,
+                               struct type *type)
+{
+  struct value *v;
+  int src,                     /* Index into the source area. */
+    targ,                      /* Index into the target area. */
+    i, srcBitsLeft,            /* Number of source bits left to move. */
+    nsrc, ntarg,               /* Number of source and target bytes. */
+    unusedLS,                  /* Number of bits in next significant
+                                * byte of source that are unused. */
+    accumSize;                 /* Number of meaningful bits in accum */
+  unsigned char *bytes;                /* First byte containing data to unpack. */
+  unsigned char *unpacked;
+  unsigned long accum;         /* Staging area for bits being transferred */
+  unsigned char sign;
+  int len = (bit_size + bit_offset + HOST_CHAR_BIT - 1) / 8;
+  /* Transmit bytes from least to most significant; delta is the
+   * direction the indices move. */
+  int delta = BITS_BIG_ENDIAN ? -1 : 1;
+
+  CHECK_TYPEDEF (type);
+
+  if (obj == NULL)
+    {
+      v = allocate_value (type);
+      bytes = (unsigned char *) (valaddr + offset);
+    }
+  else if (VALUE_LAZY (obj))
+    {
+      v = value_at (type,
+                   VALUE_ADDRESS (obj) + VALUE_OFFSET (obj) + offset, NULL);
+      bytes = (unsigned char *) alloca (len);
+      read_memory (VALUE_ADDRESS (v), bytes, len);
+    }
+  else
+    {
+      v = allocate_value (type);
+      bytes = (unsigned char *) VALUE_CONTENTS (obj) + offset;
+    }
+
+  if (obj != NULL)
+    {
+      VALUE_LVAL (v) = VALUE_LVAL (obj);
+      if (VALUE_LVAL (obj) == lval_internalvar)
+       VALUE_LVAL (v) = lval_internalvar_component;
+      VALUE_ADDRESS (v) = VALUE_ADDRESS (obj) + VALUE_OFFSET (obj) + offset;
+      VALUE_BITPOS (v) = bit_offset + VALUE_BITPOS (obj);
+      VALUE_BITSIZE (v) = bit_size;
+      if (VALUE_BITPOS (v) >= HOST_CHAR_BIT)
+       {
+         VALUE_ADDRESS (v) += 1;
+         VALUE_BITPOS (v) -= HOST_CHAR_BIT;
+       }
+    }
+  else
+    VALUE_BITSIZE (v) = bit_size;
+  unpacked = (unsigned char *) VALUE_CONTENTS (v);
+
+  srcBitsLeft = bit_size;
+  nsrc = len;
+  ntarg = TYPE_LENGTH (type);
+  sign = 0;
+  if (bit_size == 0)
+    {
+      memset (unpacked, 0, TYPE_LENGTH (type));
+      return v;
+    }
+  else if (BITS_BIG_ENDIAN)
+    {
+      src = len - 1;
+      if (has_negatives (type) &&
+         ((bytes[0] << bit_offset) & (1 << (HOST_CHAR_BIT - 1))))
+       sign = ~0;
+
+      unusedLS =
+       (HOST_CHAR_BIT - (bit_size + bit_offset) % HOST_CHAR_BIT)
+       % HOST_CHAR_BIT;
+
+      switch (TYPE_CODE (type))
+       {
+       case TYPE_CODE_ARRAY:
+       case TYPE_CODE_UNION:
+       case TYPE_CODE_STRUCT:
+         /* Non-scalar values must be aligned at a byte boundary. */
+         accumSize =
+           (HOST_CHAR_BIT - bit_size % HOST_CHAR_BIT) % HOST_CHAR_BIT;
+         /* And are placed at the beginning (most-significant) bytes
+          * of the target. */
+         targ = src;
+         break;
+       default:
+         accumSize = 0;
+         targ = TYPE_LENGTH (type) - 1;
+         break;
+       }
+    }
+  else
+    {
+      int sign_bit_offset = (bit_size + bit_offset - 1) % 8;
+
+      src = targ = 0;
+      unusedLS = bit_offset;
+      accumSize = 0;
+
+      if (has_negatives (type) && (bytes[len - 1] & (1 << sign_bit_offset)))
+       sign = ~0;
+    }
+
+  accum = 0;
+  while (nsrc > 0)
+    {
+      /* Mask for removing bits of the next source byte that are not
+       * part of the value. */
+      unsigned int unusedMSMask =
+       (1 << (srcBitsLeft >= HOST_CHAR_BIT ? HOST_CHAR_BIT : srcBitsLeft)) -
+       1;
+      /* Sign-extend bits for this byte. */
+      unsigned int signMask = sign & ~unusedMSMask;
+      accum |=
+       (((bytes[src] >> unusedLS) & unusedMSMask) | signMask) << accumSize;
+      accumSize += HOST_CHAR_BIT - unusedLS;
+      if (accumSize >= HOST_CHAR_BIT)
+       {
+         unpacked[targ] = accum & ~(~0L << HOST_CHAR_BIT);
+         accumSize -= HOST_CHAR_BIT;
+         accum >>= HOST_CHAR_BIT;
+         ntarg -= 1;
+         targ += delta;
+       }
+      srcBitsLeft -= HOST_CHAR_BIT - unusedLS;
+      unusedLS = 0;
+      nsrc -= 1;
+      src += delta;
+    }
+  while (ntarg > 0)
+    {
+      accum |= sign << accumSize;
+      unpacked[targ] = accum & ~(~0L << HOST_CHAR_BIT);
+      accumSize -= HOST_CHAR_BIT;
+      accum >>= HOST_CHAR_BIT;
+      ntarg -= 1;
+      targ += delta;
+    }
+
+  return v;
+}
+
+/* Move N bits from SOURCE, starting at bit offset SRC_OFFSET to
+   TARGET, starting at bit offset TARG_OFFSET.  SOURCE and TARGET must
+   not overlap. */
+static void
+move_bits (char *target, int targ_offset, char *source, int src_offset, int n)
+{
+  unsigned int accum, mask;
+  int accum_bits, chunk_size;
+
+  target += targ_offset / HOST_CHAR_BIT;
+  targ_offset %= HOST_CHAR_BIT;
+  source += src_offset / HOST_CHAR_BIT;
+  src_offset %= HOST_CHAR_BIT;
+  if (BITS_BIG_ENDIAN)
+    {
+      accum = (unsigned char) *source;
+      source += 1;
+      accum_bits = HOST_CHAR_BIT - src_offset;
+
+      while (n > 0)
+       {
+         int unused_right;
+         accum = (accum << HOST_CHAR_BIT) + (unsigned char) *source;
+         accum_bits += HOST_CHAR_BIT;
+         source += 1;
+         chunk_size = HOST_CHAR_BIT - targ_offset;
+         if (chunk_size > n)
+           chunk_size = n;
+         unused_right = HOST_CHAR_BIT - (chunk_size + targ_offset);
+         mask = ((1 << chunk_size) - 1) << unused_right;
+         *target =
+           (*target & ~mask)
+           | ((accum >> (accum_bits - chunk_size - unused_right)) & mask);
+         n -= chunk_size;
+         accum_bits -= chunk_size;
+         target += 1;
+         targ_offset = 0;
+       }
+    }
+  else
+    {
+      accum = (unsigned char) *source >> src_offset;
+      source += 1;
+      accum_bits = HOST_CHAR_BIT - src_offset;
+
+      while (n > 0)
+       {
+         accum = accum + ((unsigned char) *source << accum_bits);
+         accum_bits += HOST_CHAR_BIT;
+         source += 1;
+         chunk_size = HOST_CHAR_BIT - targ_offset;
+         if (chunk_size > n)
+           chunk_size = n;
+         mask = ((1 << chunk_size) - 1) << targ_offset;
+         *target = (*target & ~mask) | ((accum << targ_offset) & mask);
+         n -= chunk_size;
+         accum_bits -= chunk_size;
+         accum >>= chunk_size;
+         target += 1;
+         targ_offset = 0;
+       }
+    }
+}
+
+
+/* Store the contents of FROMVAL into the location of TOVAL.
+   Return a new value with the location of TOVAL and contents of
+   FROMVAL.   Handles assignment into packed fields that have
+   floating-point or non-scalar types. */
+
+static struct value *
+ada_value_assign (struct value *toval, struct value *fromval)
+{
+  struct type *type = VALUE_TYPE (toval);
+  int bits = VALUE_BITSIZE (toval);
+
+  if (!toval->modifiable)
+    error ("Left operand of assignment is not a modifiable lvalue.");
+
+  COERCE_REF (toval);
+
+  if (VALUE_LVAL (toval) == lval_memory
+      && bits > 0
+      && (TYPE_CODE (type) == TYPE_CODE_FLT
+         || TYPE_CODE (type) == TYPE_CODE_STRUCT))
+    {
+      int len =
+       (VALUE_BITPOS (toval) + bits + HOST_CHAR_BIT - 1) / HOST_CHAR_BIT;
+      char *buffer = (char *) alloca (len);
+      struct value *val;
+
+      if (TYPE_CODE (type) == TYPE_CODE_FLT)
+       fromval = value_cast (type, fromval);
+
+      read_memory (VALUE_ADDRESS (toval) + VALUE_OFFSET (toval), buffer, len);
+      if (BITS_BIG_ENDIAN)
+       move_bits (buffer, VALUE_BITPOS (toval),
+                  VALUE_CONTENTS (fromval),
+                  TYPE_LENGTH (VALUE_TYPE (fromval)) * TARGET_CHAR_BIT -
+                  bits, bits);
+      else
+       move_bits (buffer, VALUE_BITPOS (toval), VALUE_CONTENTS (fromval),
+                  0, bits);
+      write_memory (VALUE_ADDRESS (toval) + VALUE_OFFSET (toval), buffer,
+                   len);
+
+      val = value_copy (toval);
+      memcpy (VALUE_CONTENTS_RAW (val), VALUE_CONTENTS (fromval),
+             TYPE_LENGTH (type));
+      VALUE_TYPE (val) = type;
+
+      return val;
+    }
+
+  return value_assign (toval, fromval);
+}
+
+
+/* The value of the element of array ARR at the ARITY indices given in IND. 
+   ARR may be either a simple array, GNAT array descriptor, or pointer 
+   thereto.  */
+
+struct value *
+ada_value_subscript (struct value *arr, int arity, struct value **ind)
+{
+  int k;
+  struct value *elt;
+  struct type *elt_type;
+
+  elt = ada_coerce_to_simple_array (arr);
+
+  elt_type = check_typedef (VALUE_TYPE (elt));
+  if (TYPE_CODE (elt_type) == TYPE_CODE_ARRAY
+      && TYPE_FIELD_BITSIZE (elt_type, 0) > 0)
+    return value_subscript_packed (elt, arity, ind);
+
+  for (k = 0; k < arity; k += 1)
+    {
+      if (TYPE_CODE (elt_type) != TYPE_CODE_ARRAY)
+       error ("too many subscripts (%d expected)", k);
+      elt = value_subscript (elt, value_pos_atr (ind[k]));
+    }
+  return elt;
+}
+
+/* Assuming ARR is a pointer to a standard GDB array of type TYPE, the
+   value of the element of *ARR at the ARITY indices given in
+   IND. Does not read the entire array into memory. */
+
+struct value *
+ada_value_ptr_subscript (struct value *arr, struct type *type, int arity,
+                        struct value **ind)
+{
+  int k;
+
+  for (k = 0; k < arity; k += 1)
+    {
+      LONGEST lwb, upb;
+      struct value *idx;
+
+      if (TYPE_CODE (type) != TYPE_CODE_ARRAY)
+       error ("too many subscripts (%d expected)", k);
+      arr = value_cast (lookup_pointer_type (TYPE_TARGET_TYPE (type)),
+                       value_copy (arr));
+      get_discrete_bounds (TYPE_INDEX_TYPE (type), &lwb, &upb);
+      if (lwb == 0)
+       idx = ind[k];
+      else
+       idx = value_sub (ind[k], value_from_longest (builtin_type_int, lwb));
+      arr = value_add (arr, idx);
+      type = TYPE_TARGET_TYPE (type);
+    }
+
+  return value_ind (arr);
+}
+
+/* If type is a record type in the form of a standard GNAT array
+   descriptor, returns the number of dimensions for type.  If arr is a
+   simple array, returns the number of "array of"s that prefix its
+   type designation. Otherwise, returns 0. */
+
+int
+ada_array_arity (struct type *type)
+{
+  int arity;
+
+  if (type == NULL)
+    return 0;
+
+  type = desc_base_type (type);
+
+  arity = 0;
+  if (TYPE_CODE (type) == TYPE_CODE_STRUCT)
+    return desc_arity (desc_bounds_type (type));
+  else
+    while (TYPE_CODE (type) == TYPE_CODE_ARRAY)
+      {
+       arity += 1;
+       type = check_typedef (TYPE_TARGET_TYPE (type));
+      }
+
+  return arity;
+}
+
+/* If TYPE is a record type in the form of a standard GNAT array
+   descriptor or a simple array type, returns the element type for
+   TYPE after indexing by NINDICES indices, or by all indices if
+   NINDICES is -1. Otherwise, returns NULL. */
+
+struct type *
+ada_array_element_type (struct type *type, int nindices)
+{
+  type = desc_base_type (type);
+
+  if (TYPE_CODE (type) == TYPE_CODE_STRUCT)
+    {
+      int k;
+      struct type *p_array_type;
+
+      p_array_type = desc_data_type (type);
+
+      k = ada_array_arity (type);
+      if (k == 0)
+       return NULL;
+
+      /* Initially p_array_type = elt_type(*)[]...(k times)...[] */
+      if (nindices >= 0 && k > nindices)
+       k = nindices;
+      p_array_type = TYPE_TARGET_TYPE (p_array_type);
+      while (k > 0 && p_array_type != NULL)
+       {
+         p_array_type = check_typedef (TYPE_TARGET_TYPE (p_array_type));
+         k -= 1;
+       }
+      return p_array_type;
+    }
+  else if (TYPE_CODE (type) == TYPE_CODE_ARRAY)
+    {
+      while (nindices != 0 && TYPE_CODE (type) == TYPE_CODE_ARRAY)
+       {
+         type = TYPE_TARGET_TYPE (type);
+         nindices -= 1;
+       }
+      return type;
+    }
+
+  return NULL;
+}
+
+/* The type of nth index in arrays of given type (n numbering from 1).  Does 
+   not examine memory. */
+
+struct type *
+ada_index_type (struct type *type, int n)
+{
+  type = desc_base_type (type);
+
+  if (n > ada_array_arity (type))
+    return NULL;
+
+  if (ada_is_simple_array (type))
+    {
+      int i;
+
+      for (i = 1; i < n; i += 1)
+       type = TYPE_TARGET_TYPE (type);
+
+      return TYPE_TARGET_TYPE (TYPE_FIELD_TYPE (type, 0));
+    }
+  else
+    return desc_index_type (desc_bounds_type (type), n);
+}
+
+/* Given that arr is an array type, returns the lower bound of the
+   Nth index (numbering from 1) if WHICH is 0, and the upper bound if
+   WHICH is 1. This returns bounds 0 .. -1 if ARR_TYPE is an
+   array-descriptor type.  If TYPEP is non-null, *TYPEP is set to the 
+   bounds type.  It works for other arrays with bounds supplied by 
+   run-time quantities other than discriminants. */
+
+LONGEST
+ada_array_bound_from_type (struct type * arr_type, int n, int which,
+                          struct type ** typep)
+{
+  struct type *type;
+  struct type *index_type_desc;
+
+  if (ada_is_packed_array_type (arr_type))
+    arr_type = decode_packed_array_type (arr_type);
+
+  if (arr_type == NULL || !ada_is_simple_array (arr_type))
+    {
+      if (typep != NULL)
+       *typep = builtin_type_int;
+      return (LONGEST) - which;
+    }
+
+  if (TYPE_CODE (arr_type) == TYPE_CODE_PTR)
+    type = TYPE_TARGET_TYPE (arr_type);
+  else
+    type = arr_type;
+
+  index_type_desc = ada_find_parallel_type (type, "___XA");
+  if (index_type_desc == NULL)
+    {
+      struct type *range_type;
+      struct type *index_type;
+
+      while (n > 1)
+       {
+         type = TYPE_TARGET_TYPE (type);
+         n -= 1;
+       }
+
+      range_type = TYPE_INDEX_TYPE (type);
+      index_type = TYPE_TARGET_TYPE (range_type);
+      if (TYPE_CODE (index_type) == TYPE_CODE_UNDEF)
+       index_type = builtin_type_long;
+      if (typep != NULL)
+       *typep = index_type;
+      return
+       (LONGEST) (which == 0
+                  ? TYPE_LOW_BOUND (range_type)
+                  : TYPE_HIGH_BOUND (range_type));
+    }
+  else
+    {
+      struct type *index_type =
+       to_fixed_range_type (TYPE_FIELD_NAME (index_type_desc, n - 1),
+                            NULL, TYPE_OBJFILE (arr_type));
+      if (typep != NULL)
+       *typep = TYPE_TARGET_TYPE (index_type);
+      return
+       (LONGEST) (which == 0
+                  ? TYPE_LOW_BOUND (index_type)
+                  : TYPE_HIGH_BOUND (index_type));
+    }
+}
+
+/* Given that arr is an array value, returns the lower bound of the
+   nth index (numbering from 1) if which is 0, and the upper bound if
+   which is 1. This routine will also work for arrays with bounds
+   supplied by run-time quantities other than discriminants. */
+
+struct value *
+ada_array_bound (struct value *arr, int n, int which)
+{
+  struct type *arr_type = VALUE_TYPE (arr);
+
+  if (ada_is_packed_array_type (arr_type))
+    return ada_array_bound (decode_packed_array (arr), n, which);
+  else if (ada_is_simple_array (arr_type))
+    {
+      struct type *type;
+      LONGEST v = ada_array_bound_from_type (arr_type, n, which, &type);
+      return value_from_longest (type, v);
+    }
+  else
+    return desc_one_bound (desc_bounds (arr), n, which);
+}
+
+/* Given that arr is an array value, returns the length of the
+   nth index.  This routine will also work for arrays with bounds
+   supplied by run-time quantities other than discriminants. Does not
+   work for arrays indexed by enumeration types with representation
+   clauses at the moment. */
+
+struct value *
+ada_array_length (struct value *arr, int n)
+{
+  struct type *arr_type = check_typedef (VALUE_TYPE (arr));
+  struct type *index_type_desc;
+
+  if (ada_is_packed_array_type (arr_type))
+    return ada_array_length (decode_packed_array (arr), n);
+
+  if (ada_is_simple_array (arr_type))
+    {
+      struct type *type;
+      LONGEST v =
+       ada_array_bound_from_type (arr_type, n, 1, &type) -
+       ada_array_bound_from_type (arr_type, n, 0, NULL) + 1;
+      return value_from_longest (type, v);
+    }
+  else
+    return
+      value_from_longest (builtin_type_ada_int,
+                         value_as_long (desc_one_bound (desc_bounds (arr),
+                                                        n, 1))
+                         - value_as_long (desc_one_bound (desc_bounds (arr),
+                                                          n, 0)) + 1);
+}
+\f
+
+                               /* Name resolution */
+
+/* The "demangled" name for the user-definable Ada operator corresponding
+   to op. */
+
+static const char *
+ada_op_name (enum exp_opcode op)
+{
+  int i;
+
+  for (i = 0; ada_opname_table[i].mangled != NULL; i += 1)
+    {
+      if (ada_opname_table[i].op == op)
+       return ada_opname_table[i].demangled;
+    }
+  error ("Could not find operator name for opcode");
+}
+
+
+/* Same as evaluate_type (*EXP), but resolves ambiguous symbol 
+   references (OP_UNRESOLVED_VALUES) and converts operators that are 
+   user-defined into appropriate function calls.  If CONTEXT_TYPE is 
+   non-null, it provides a preferred result type [at the moment, only
+   type void has any effect---causing procedures to be preferred over
+   functions in calls].  A null CONTEXT_TYPE indicates that a non-void
+   return type is preferred.  The variable unresolved_names contains a list
+   of character strings referenced by expout that should be freed.  
+   May change (expand) *EXP.  */
+
+void
+ada_resolve (struct expression **expp, struct type *context_type)
+{
+  int pc;
+  pc = 0;
+  ada_resolve_subexp (expp, &pc, 1, context_type);
+}
+
+/* Resolve the operator of the subexpression beginning at 
+   position *POS of *EXPP. "Resolving" consists of replacing
+   OP_UNRESOLVED_VALUE with an appropriate OP_VAR_VALUE, replacing
+   built-in operators with function calls to user-defined operators,
+   where appropriate, and (when DEPROCEDURE_P is non-zero), converting
+   function-valued variables into parameterless calls.  May expand
+   EXP. The CONTEXT_TYPE functions as in ada_resolve, above. */
+
+static struct value *
+ada_resolve_subexp (struct expression **expp, int *pos, int deprocedure_p,
+                   struct type *context_type)
+{
+  int pc = *pos;
+  int i;
+  struct expression *exp;      /* Convenience: == *expp */
+  enum exp_opcode op = (*expp)->elts[pc].opcode;
+  struct value **argvec;       /* Vector of operand types (alloca'ed). */
+  int nargs;                   /* Number of operands */
+
+  argvec = NULL;
+  nargs = 0;
+  exp = *expp;
+
+  /* Pass one: resolve operands, saving their types and updating *pos. */
+  switch (op)
+    {
+    case OP_VAR_VALUE:
+      /*    case OP_UNRESOLVED_VALUE: */
+      /* FIXME:  OP_UNRESOLVED_VALUE should be defined in expression.h */
+      *pos += 4;
+      break;
+
+    case OP_FUNCALL:
+      nargs = longest_to_int (exp->elts[pc + 1].longconst) + 1;
+      /* FIXME:  OP_UNRESOLVED_VALUE should be defined in expression.h */
+      /*      if (exp->elts[pc+3].opcode == OP_UNRESOLVED_VALUE)        
+         {
+         *pos += 7;
+
+         argvec = (struct value* *) alloca (sizeof (struct value*) * (nargs + 1));
+         for (i = 0; i < nargs-1; i += 1)
+         argvec[i] = ada_resolve_subexp (expp, pos, 1, NULL);
+         argvec[i] = NULL;
+         }
+         else
+         {
+         *pos += 3;
+         ada_resolve_subexp (expp, pos, 0, NULL);
+         for (i = 1; i < nargs; i += 1)
+         ada_resolve_subexp (expp, pos, 1, NULL);
+         }
+       */
+      exp = *expp;
+      break;
+
+      /* FIXME:  UNOP_QUAL should be defined in expression.h */
+      /*    case UNOP_QUAL:
+         nargs = 1;
+         *pos += 3;
+         ada_resolve_subexp (expp, pos, 1, exp->elts[pc + 1].type);
+         exp = *expp;
+         break;
+       */
+      /* FIXME:  OP_ATTRIBUTE should be defined in expression.h */
+      /*    case OP_ATTRIBUTE:
+         nargs = longest_to_int (exp->elts[pc + 1].longconst) + 1;
+         *pos += 4;
+         for (i = 0; i < nargs; i += 1)
+         ada_resolve_subexp (expp, pos, 1, NULL);
+         exp = *expp;
+         break;
+       */
+    case UNOP_ADDR:
+      nargs = 1;
+      *pos += 1;
+      ada_resolve_subexp (expp, pos, 0, NULL);
+      exp = *expp;
+      break;
+
+    case BINOP_ASSIGN:
+      {
+       struct value *arg1;
+       nargs = 2;
+       *pos += 1;
+       arg1 = ada_resolve_subexp (expp, pos, 0, NULL);
+       if (arg1 == NULL)
+         ada_resolve_subexp (expp, pos, 1, NULL);
+       else
+         ada_resolve_subexp (expp, pos, 1, VALUE_TYPE (arg1));
+       break;
+      }
+
+    default:
+      switch (op)
+       {
+       default:
+         error ("Unexpected operator during name resolution");
+       case UNOP_CAST:
+         /*    case UNOP_MBR:
+            nargs = 1;
+            *pos += 3;
+            break;
+          */
+       case BINOP_ADD:
+       case BINOP_SUB:
+       case BINOP_MUL:
+       case BINOP_DIV:
+       case BINOP_REM:
+       case BINOP_MOD:
+       case BINOP_EXP:
+       case BINOP_CONCAT:
+       case BINOP_LOGICAL_AND:
+       case BINOP_LOGICAL_OR:
+       case BINOP_BITWISE_AND:
+       case BINOP_BITWISE_IOR:
+       case BINOP_BITWISE_XOR:
+
+       case BINOP_EQUAL:
+       case BINOP_NOTEQUAL:
+       case BINOP_LESS:
+       case BINOP_GTR:
+       case BINOP_LEQ:
+       case BINOP_GEQ:
+
+       case BINOP_REPEAT:
+       case BINOP_SUBSCRIPT:
+       case BINOP_COMMA:
+         nargs = 2;
+         *pos += 1;
+         break;
+
+       case UNOP_NEG:
+       case UNOP_PLUS:
+       case UNOP_LOGICAL_NOT:
+       case UNOP_ABS:
+       case UNOP_IND:
+         nargs = 1;
+         *pos += 1;
+         break;
+
+       case OP_LONG:
+       case OP_DOUBLE:
+       case OP_VAR_VALUE:
+         *pos += 4;
+         break;
+
+       case OP_TYPE:
+       case OP_BOOL:
+       case OP_LAST:
+       case OP_REGISTER:
+       case OP_INTERNALVAR:
+         *pos += 3;
+         break;
+
+       case UNOP_MEMVAL:
+         *pos += 3;
+         nargs = 1;
+         break;
+
+       case STRUCTOP_STRUCT:
+       case STRUCTOP_PTR:
+         nargs = 1;
+         *pos += 4 + BYTES_TO_EXP_ELEM (exp->elts[pc + 1].longconst + 1);
+         break;
+
+       case OP_ARRAY:
+         *pos += 4;
+         nargs = longest_to_int (exp->elts[pc + 2].longconst) + 1;
+         nargs -= longest_to_int (exp->elts[pc + 1].longconst);
+         /* A null array contains one dummy element to give the type. */
+         /*      if (nargs == 0)
+            nargs = 1;
+            break; */
+
+       case TERNOP_SLICE:
+         /* FIXME: TERNOP_MBR should be defined in expression.h */
+         /*    case TERNOP_MBR:
+            *pos += 1;
+            nargs = 3;
+            break;
+          */
+         /* FIXME: BINOP_MBR should be defined in expression.h */
+         /*    case BINOP_MBR:
+            *pos += 3;
+            nargs = 2;
+            break; */
+       }
+
+      argvec =
+       (struct value * *) alloca (sizeof (struct value *) * (nargs + 1));
+      for (i = 0; i < nargs; i += 1)
+       argvec[i] = ada_resolve_subexp (expp, pos, 1, NULL);
+      argvec[i] = NULL;
+      exp = *expp;
+      break;
+    }
+
+  /* Pass two: perform any resolution on principal operator. */
+  switch (op)
+    {
+    default:
+      break;
+
+      /* FIXME:  OP_UNRESOLVED_VALUE should be defined in expression.h */
+      /*    case OP_UNRESOLVED_VALUE:
+         {
+         struct symbol** candidate_syms;
+         struct block** candidate_blocks;
+         int n_candidates;
+
+         n_candidates = ada_lookup_symbol_list (exp->elts[pc + 2].name,
+         exp->elts[pc + 1].block,
+         VAR_NAMESPACE,
+         &candidate_syms,
+         &candidate_blocks);
+
+         if (n_candidates > 1) 
+         { */
+      /* Types tend to get re-introduced locally, so if there
+         are any local symbols that are not types, first filter
+   out all types. *//*
+   int j;
+   for (j = 0; j < n_candidates; j += 1) 
+   switch (SYMBOL_CLASS (candidate_syms[j])) 
+   {
+   case LOC_REGISTER:
+   case LOC_ARG:
+   case LOC_REF_ARG:
+   case LOC_REGPARM:
+   case LOC_REGPARM_ADDR:
+   case LOC_LOCAL:
+   case LOC_LOCAL_ARG:
+   case LOC_BASEREG:
+   case LOC_BASEREG_ARG:
+   goto FoundNonType;
+   default:
+   break;
+   }
+   FoundNonType:
+   if (j < n_candidates) 
+   {
+   j = 0;
+   while (j < n_candidates) 
+   {
+   if (SYMBOL_CLASS (candidate_syms[j]) == LOC_TYPEDEF)
+   {
+   candidate_syms[j] = candidate_syms[n_candidates-1];
+   candidate_blocks[j] = candidate_blocks[n_candidates-1];
+   n_candidates -= 1;
+   }
+   else
+   j += 1;
+   }
+   }
+   }
+
+   if (n_candidates == 0)
+   error ("No definition found for %s", 
+   ada_demangle (exp->elts[pc + 2].name));
+   else if (n_candidates == 1)
+   i = 0;
+   else if (deprocedure_p 
+   && ! is_nonfunction (candidate_syms, n_candidates))
+   {
+   i = ada_resolve_function (candidate_syms, candidate_blocks,
+   n_candidates, NULL, 0,
+   exp->elts[pc + 2].name, context_type);
+   if (i < 0) 
+   error ("Could not find a match for %s", 
+   ada_demangle (exp->elts[pc + 2].name));
+   }
+   else 
+   {
+   printf_filtered ("Multiple matches for %s\n", 
+   ada_demangle (exp->elts[pc+2].name));
+   user_select_syms (candidate_syms, candidate_blocks, 
+   n_candidates, 1);
+   i = 0;
+   }
+
+   exp->elts[pc].opcode = exp->elts[pc + 3].opcode = OP_VAR_VALUE;
+   exp->elts[pc + 1].block = candidate_blocks[i];
+   exp->elts[pc + 2].symbol = candidate_syms[i];
+   if (innermost_block == NULL ||
+   contained_in (candidate_blocks[i], innermost_block))
+   innermost_block = candidate_blocks[i];
+   } */
+      /* FALL THROUGH */
+
+    case OP_VAR_VALUE:
+      if (deprocedure_p &&
+         TYPE_CODE (SYMBOL_TYPE (exp->elts[pc + 2].symbol)) ==
+         TYPE_CODE_FUNC)
+       {
+         replace_operator_with_call (expp, pc, 0, 0,
+                                     exp->elts[pc + 2].symbol,
+                                     exp->elts[pc + 1].block);
+         exp = *expp;
+       }
+      break;
+
+    case OP_FUNCALL:
+      {
+       /* FIXME:  OP_UNRESOLVED_VALUE should be defined in expression.h */
+       /*      if (exp->elts[pc+3].opcode == OP_UNRESOLVED_VALUE)      
+          {
+          struct symbol** candidate_syms;
+          struct block** candidate_blocks;
+          int n_candidates;
+
+          n_candidates = ada_lookup_symbol_list (exp->elts[pc + 5].name,
+          exp->elts[pc + 4].block,
+          VAR_NAMESPACE,
+          &candidate_syms,
+          &candidate_blocks);
+          if (n_candidates == 1)
+          i = 0;
+          else
+          {
+          i = ada_resolve_function (candidate_syms, candidate_blocks,
+          n_candidates, argvec, nargs-1,
+          exp->elts[pc + 5].name, context_type);
+          if (i < 0) 
+          error ("Could not find a match for %s", 
+          ada_demangle (exp->elts[pc + 5].name));
+          }
+
+          exp->elts[pc + 3].opcode = exp->elts[pc + 6].opcode = OP_VAR_VALUE;
+          exp->elts[pc + 4].block = candidate_blocks[i];
+          exp->elts[pc + 5].symbol = candidate_syms[i];
+          if (innermost_block == NULL ||
+          contained_in (candidate_blocks[i], innermost_block))
+          innermost_block = candidate_blocks[i];
+          } */
+
+      }
+      break;
+    case BINOP_ADD:
+    case BINOP_SUB:
+    case BINOP_MUL:
+    case BINOP_DIV:
+    case BINOP_REM:
+    case BINOP_MOD:
+    case BINOP_CONCAT:
+    case BINOP_BITWISE_AND:
+    case BINOP_BITWISE_IOR:
+    case BINOP_BITWISE_XOR:
+    case BINOP_EQUAL:
+    case BINOP_NOTEQUAL:
+    case BINOP_LESS:
+    case BINOP_GTR:
+    case BINOP_LEQ:
+    case BINOP_GEQ:
+    case BINOP_EXP:
+    case UNOP_NEG:
+    case UNOP_PLUS:
+    case UNOP_LOGICAL_NOT:
+    case UNOP_ABS:
+      if (possible_user_operator_p (op, argvec))
+       {
+         struct symbol **candidate_syms;
+         struct block **candidate_blocks;
+         int n_candidates;
+
+         n_candidates =
+           ada_lookup_symbol_list (ada_mangle (ada_op_name (op)),
+                                   (struct block *) NULL, VAR_NAMESPACE,
+                                   &candidate_syms, &candidate_blocks);
+         i =
+           ada_resolve_function (candidate_syms, candidate_blocks,
+                                 n_candidates, argvec, nargs,
+                                 ada_op_name (op), NULL);
+         if (i < 0)
+           break;
+
+         replace_operator_with_call (expp, pc, nargs, 1,
+                                     candidate_syms[i], candidate_blocks[i]);
+         exp = *expp;
+       }
+      break;
+    }
+
+  *pos = pc;
+  return evaluate_subexp_type (exp, pos);
+}
+
+/* Return non-zero if formal type FTYPE matches actual type ATYPE.  If
+   MAY_DEREF is non-zero, the formal may be a pointer and the actual 
+   a non-pointer. */
+/* The term "match" here is rather loose.  The match is heuristic and
+   liberal.  FIXME: TOO liberal, in fact. */
+
+static int
+ada_type_match (struct type *ftype, struct type *atype, int may_deref)
+{
+  CHECK_TYPEDEF (ftype);
+  CHECK_TYPEDEF (atype);
+
+  if (TYPE_CODE (ftype) == TYPE_CODE_REF)
+    ftype = TYPE_TARGET_TYPE (ftype);
+  if (TYPE_CODE (atype) == TYPE_CODE_REF)
+    atype = TYPE_TARGET_TYPE (atype);
+
+  if (TYPE_CODE (ftype) == TYPE_CODE_VOID
+      || TYPE_CODE (atype) == TYPE_CODE_VOID)
+    return 1;
+
+  switch (TYPE_CODE (ftype))
+    {
+    default:
+      return 1;
+    case TYPE_CODE_PTR:
+      if (TYPE_CODE (atype) == TYPE_CODE_PTR)
+       return ada_type_match (TYPE_TARGET_TYPE (ftype),
+                              TYPE_TARGET_TYPE (atype), 0);
+      else
+       return (may_deref &&
+               ada_type_match (TYPE_TARGET_TYPE (ftype), atype, 0));
+    case TYPE_CODE_INT:
+    case TYPE_CODE_ENUM:
+    case TYPE_CODE_RANGE:
+      switch (TYPE_CODE (atype))
+       {
+       case TYPE_CODE_INT:
+       case TYPE_CODE_ENUM:
+       case TYPE_CODE_RANGE:
+         return 1;
+       default:
+         return 0;
+       }
+
+    case TYPE_CODE_ARRAY:
+      return (TYPE_CODE (atype) == TYPE_CODE_ARRAY
+             || ada_is_array_descriptor (atype));
+
+    case TYPE_CODE_STRUCT:
+      if (ada_is_array_descriptor (ftype))
+       return (TYPE_CODE (atype) == TYPE_CODE_ARRAY
+               || ada_is_array_descriptor (atype));
+      else
+       return (TYPE_CODE (atype) == TYPE_CODE_STRUCT
+               && !ada_is_array_descriptor (atype));
+
+    case TYPE_CODE_UNION:
+    case TYPE_CODE_FLT:
+      return (TYPE_CODE (atype) == TYPE_CODE (ftype));
+    }
+}
+
+/* Return non-zero if the formals of FUNC "sufficiently match" the
+   vector of actual argument types ACTUALS of size N_ACTUALS.  FUNC
+   may also be an enumeral, in which case it is treated as a 0-
+   argument function. */
+
+static int
+ada_args_match (struct symbol *func, struct value **actuals, int n_actuals)
+{
+  int i;
+  struct type *func_type = SYMBOL_TYPE (func);
+
+  if (SYMBOL_CLASS (func) == LOC_CONST &&
+      TYPE_CODE (func_type) == TYPE_CODE_ENUM)
+    return (n_actuals == 0);
+  else if (func_type == NULL || TYPE_CODE (func_type) != TYPE_CODE_FUNC)
+    return 0;
+
+  if (TYPE_NFIELDS (func_type) != n_actuals)
+    return 0;
+
+  for (i = 0; i < n_actuals; i += 1)
+    {
+      struct type *ftype = check_typedef (TYPE_FIELD_TYPE (func_type, i));
+      struct type *atype = check_typedef (VALUE_TYPE (actuals[i]));
+
+      if (!ada_type_match (TYPE_FIELD_TYPE (func_type, i),
+                          VALUE_TYPE (actuals[i]), 1))
+       return 0;
+    }
+  return 1;
+}
+
+/* False iff function type FUNC_TYPE definitely does not produce a value
+   compatible with type CONTEXT_TYPE.  Conservatively returns 1 if
+   FUNC_TYPE is not a valid function type with a non-null return type
+   or an enumerated type.  A null CONTEXT_TYPE indicates any non-void type.  */
+
+static int
+return_match (struct type *func_type, struct type *context_type)
+{
+  struct type *return_type;
+
+  if (func_type == NULL)
+    return 1;
+
+  /* FIXME: base_type should be declared in gdbtypes.h, implemented in valarith.c */
+  /*  if (TYPE_CODE (func_type) == TYPE_CODE_FUNC)
+     return_type = base_type (TYPE_TARGET_TYPE (func_type));
+     else 
+     return_type = base_type (func_type); */
+  if (return_type == NULL)
+    return 1;
+
+  /* FIXME: base_type should be declared in gdbtypes.h, implemented in valarith.c */
+  /*  context_type = base_type (context_type); */
+
+  if (TYPE_CODE (return_type) == TYPE_CODE_ENUM)
+    return context_type == NULL || return_type == context_type;
+  else if (context_type == NULL)
+    return TYPE_CODE (return_type) != TYPE_CODE_VOID;
+  else
+    return TYPE_CODE (return_type) == TYPE_CODE (context_type);
+}
+
+
+/* Return the index in SYMS[0..NSYMS-1] of symbol for the 
+   function (if any) that matches the types of the NARGS arguments in
+   ARGS.  If CONTEXT_TYPE is non-null, and there is at least one match
+   that returns type CONTEXT_TYPE, then eliminate other matches.  If
+   CONTEXT_TYPE is null, prefer a non-void-returning function.
+   Asks the user if there is more than one match remaining.  Returns -1
+   if there is no such symbol or none is selected.  NAME is used
+   solely for messages.   May re-arrange and modify SYMS in
+   the process; the index returned is for the modified vector.  BLOCKS
+   is modified in parallel to SYMS. */
+
+int
+ada_resolve_function (struct symbol *syms[], struct block *blocks[],
+                     int nsyms, struct value **args, int nargs,
+                     const char *name, struct type *context_type)
+{
+  int k;
+  int m;                       /* Number of hits */
+  struct type *fallback;
+  struct type *return_type;
+
+  return_type = context_type;
+  if (context_type == NULL)
+    fallback = builtin_type_void;
+  else
+    fallback = NULL;
+
+  m = 0;
+  while (1)
+    {
+      for (k = 0; k < nsyms; k += 1)
+       {
+         struct type *type = check_typedef (SYMBOL_TYPE (syms[k]));
+
+         if (ada_args_match (syms[k], args, nargs)
+             && return_match (SYMBOL_TYPE (syms[k]), return_type))
+           {
+             syms[m] = syms[k];
+             if (blocks != NULL)
+               blocks[m] = blocks[k];
+             m += 1;
+           }
+       }
+      if (m > 0 || return_type == fallback)
+       break;
+      else
+       return_type = fallback;
+    }
+
+  if (m == 0)
+    return -1;
+  else if (m > 1)
+    {
+      printf_filtered ("Multiple matches for %s\n", name);
+      user_select_syms (syms, blocks, m, 1);
+      return 0;
+    }
+  return 0;
+}
+
+/* Returns true (non-zero) iff demangled name N0 should appear before N1 */
+/* in a listing of choices during disambiguation (see sort_choices, below). */
+/* The idea is that overloadings of a subprogram name from the */
+/* same package should sort in their source order.  We settle for ordering */
+/* such symbols by their trailing number (__N  or $N). */
+static int
+mangled_ordered_before (char *N0, char *N1)
+{
+  if (N1 == NULL)
+    return 0;
+  else if (N0 == NULL)
+    return 1;
+  else
+    {
+      int k0, k1;
+      for (k0 = strlen (N0) - 1; k0 > 0 && isdigit (N0[k0]); k0 -= 1)
+       ;
+      for (k1 = strlen (N1) - 1; k1 > 0 && isdigit (N1[k1]); k1 -= 1)
+       ;
+      if ((N0[k0] == '_' || N0[k0] == '$') && N0[k0 + 1] != '\000'
+         && (N1[k1] == '_' || N1[k1] == '$') && N1[k1 + 1] != '\000')
+       {
+         int n0, n1;
+         n0 = k0;
+         while (N0[n0] == '_' && n0 > 0 && N0[n0 - 1] == '_')
+           n0 -= 1;
+         n1 = k1;
+         while (N1[n1] == '_' && n1 > 0 && N1[n1 - 1] == '_')
+           n1 -= 1;
+         if (n0 == n1 && STREQN (N0, N1, n0))
+           return (atoi (N0 + k0 + 1) < atoi (N1 + k1 + 1));
+       }
+      return (strcmp (N0, N1) < 0);
+    }
+}
+
+/* Sort SYMS[0..NSYMS-1] to put the choices in a canonical order by their */
+/* mangled names, rearranging BLOCKS[0..NSYMS-1] according to the same */
+/* permutation. */
+static void
+sort_choices (struct symbol *syms[], struct block *blocks[], int nsyms)
+{
+  int i, j;
+  for (i = 1; i < nsyms; i += 1)
+    {
+      struct symbol *sym = syms[i];
+      struct block *block = blocks[i];
+      int j;
+
+      for (j = i - 1; j >= 0; j -= 1)
+       {
+         if (mangled_ordered_before (SYMBOL_NAME (syms[j]),
+                                     SYMBOL_NAME (sym)))
+           break;
+         syms[j + 1] = syms[j];
+         blocks[j + 1] = blocks[j];
+       }
+      syms[j + 1] = sym;
+      blocks[j + 1] = block;
+    }
+}
+
+/* Given a list of NSYMS symbols in SYMS and corresponding blocks in */
+/* BLOCKS, select up to MAX_RESULTS>0 by asking the user (if */
+/* necessary), returning the number selected, and setting the first */
+/* elements of SYMS and BLOCKS to the selected symbols and */
+/* corresponding blocks.  Error if no symbols selected.   BLOCKS may */
+/* be NULL, in which case it is ignored. */
+
+/* NOTE: Adapted from decode_line_2 in symtab.c, with which it ought
+   to be re-integrated one of these days. */
+
+int
+user_select_syms (struct symbol *syms[], struct block *blocks[], int nsyms,
+                 int max_results)
+{
+  int i;
+  int *chosen = (int *) alloca (sizeof (int) * nsyms);
+  int n_chosen;
+  int first_choice = (max_results == 1) ? 1 : 2;
+
+  if (max_results < 1)
+    error ("Request to select 0 symbols!");
+  if (nsyms <= 1)
+    return nsyms;
+
+  printf_unfiltered ("[0] cancel\n");
+  if (max_results > 1)
+    printf_unfiltered ("[1] all\n");
+
+  sort_choices (syms, blocks, nsyms);
+
+  for (i = 0; i < nsyms; i += 1)
+    {
+      if (syms[i] == NULL)
+       continue;
+
+      if (SYMBOL_CLASS (syms[i]) == LOC_BLOCK)
+       {
+         struct symtab_and_line sal = find_function_start_sal (syms[i], 1);
+         printf_unfiltered ("[%d] %s at %s:%d\n",
+                            i + first_choice,
+                            SYMBOL_SOURCE_NAME (syms[i]),
+                            sal.symtab == NULL
+                            ? "<no source file available>"
+                            : sal.symtab->filename, sal.line);
+         continue;
+       }
+      else
+       {
+         int is_enumeral =
+           (SYMBOL_CLASS (syms[i]) == LOC_CONST
+            && SYMBOL_TYPE (syms[i]) != NULL
+            && TYPE_CODE (SYMBOL_TYPE (syms[i])) == TYPE_CODE_ENUM);
+         struct symtab *symtab = symtab_for_sym (syms[i]);
+
+         if (SYMBOL_LINE (syms[i]) != 0 && symtab != NULL)
+           printf_unfiltered ("[%d] %s at %s:%d\n",
+                              i + first_choice,
+                              SYMBOL_SOURCE_NAME (syms[i]),
+                              symtab->filename, SYMBOL_LINE (syms[i]));
+         else if (is_enumeral && TYPE_NAME (SYMBOL_TYPE (syms[i])) != NULL)
+           {
+             printf_unfiltered ("[%d] ", i + first_choice);
+             ada_print_type (SYMBOL_TYPE (syms[i]), NULL, gdb_stdout, -1, 0);
+             printf_unfiltered ("'(%s) (enumeral)\n",
+                                SYMBOL_SOURCE_NAME (syms[i]));
+           }
+         else if (symtab != NULL)
+           printf_unfiltered (is_enumeral
+                              ? "[%d] %s in %s (enumeral)\n"
+                              : "[%d] %s at %s:?\n",
+                              i + first_choice,
+                              SYMBOL_SOURCE_NAME (syms[i]),
+                              symtab->filename);
+         else
+           printf_unfiltered (is_enumeral
+                              ? "[%d] %s (enumeral)\n"
+                              : "[%d] %s at ?\n",
+                              i + first_choice,
+                              SYMBOL_SOURCE_NAME (syms[i]));
+       }
+    }
+
+  n_chosen = get_selections (chosen, nsyms, max_results, max_results > 1,
+                            "overload-choice");
+
+  for (i = 0; i < n_chosen; i += 1)
+    {
+      syms[i] = syms[chosen[i]];
+      if (blocks != NULL)
+       blocks[i] = blocks[chosen[i]];
+    }
+
+  return n_chosen;
+}
+
+/* Read and validate a set of numeric choices from the user in the
+   range 0 .. N_CHOICES-1. Place the results in increasing
+   order in CHOICES[0 .. N-1], and return N.
+
+   The user types choices as a sequence of numbers on one line
+   separated by blanks, encoding them as follows:
+
+     + A choice of 0 means to cancel the selection, throwing an error.  
+     + If IS_ALL_CHOICE, a choice of 1 selects the entire set 0 .. N_CHOICES-1.
+     + The user chooses k by typing k+IS_ALL_CHOICE+1.
+
+   The user is not allowed to choose more than MAX_RESULTS values. 
+
+   ANNOTATION_SUFFIX, if present, is used to annotate the input
+   prompts (for use with the -f switch). */
+
+int
+get_selections (int *choices, int n_choices, int max_results,
+               int is_all_choice, char *annotation_suffix)
+{
+  int i;
+  char *args;
+  const char *prompt;
+  int n_chosen;
+  int first_choice = is_all_choice ? 2 : 1;
+
+  prompt = getenv ("PS2");
+  if (prompt == NULL)
+    prompt = ">";
+
+  printf_unfiltered ("%s ", prompt);
+  gdb_flush (gdb_stdout);
+
+  args = command_line_input ((char *) NULL, 0, annotation_suffix);
+
+  if (args == NULL)
+    error_no_arg ("one or more choice numbers");
+
+  n_chosen = 0;
+
+  /* Set choices[0 .. n_chosen-1] to the users' choices in ascending 
+     order, as given in args.   Choices are validated. */
+  while (1)
+    {
+      char *args2;
+      int choice, j;
+
+      while (isspace (*args))
+       args += 1;
+      if (*args == '\0' && n_chosen == 0)
+       error_no_arg ("one or more choice numbers");
+      else if (*args == '\0')
+       break;
+
+      choice = strtol (args, &args2, 10);
+      if (args == args2 || choice < 0
+         || choice > n_choices + first_choice - 1)
+       error ("Argument must be choice number");
+      args = args2;
+
+      if (choice == 0)
+       error ("cancelled");
+
+      if (choice < first_choice)
+       {
+         n_chosen = n_choices;
+         for (j = 0; j < n_choices; j += 1)
+           choices[j] = j;
+         break;
+       }
+      choice -= first_choice;
+
+      for (j = n_chosen - 1; j >= 0 && choice < choices[j]; j -= 1)
+       {
+       }
+
+      if (j < 0 || choice != choices[j])
+       {
+         int k;
+         for (k = n_chosen - 1; k > j; k -= 1)
+           choices[k + 1] = choices[k];
+         choices[j + 1] = choice;
+         n_chosen += 1;
+       }
+    }
+
+  if (n_chosen > max_results)
+    error ("Select no more than %d of the above", max_results);
+
+  return n_chosen;
+}
+
+/* Replace the operator of length OPLEN at position PC in *EXPP with a call */
+/* on the function identified by SYM and BLOCK, and taking NARGS */
+/* arguments.  Update *EXPP as needed to hold more space. */
+
+static void
+replace_operator_with_call (struct expression **expp, int pc, int nargs,
+                           int oplen, struct symbol *sym,
+                           struct block *block)
+{
+  /* A new expression, with 6 more elements (3 for funcall, 4 for function
+     symbol, -oplen for operator being replaced). */
+  struct expression *newexp = (struct expression *)
+    xmalloc (sizeof (struct expression)
+            + EXP_ELEM_TO_BYTES ((*expp)->nelts + 7 - oplen));
+  struct expression *exp = *expp;
+
+  newexp->nelts = exp->nelts + 7 - oplen;
+  newexp->language_defn = exp->language_defn;
+  memcpy (newexp->elts, exp->elts, EXP_ELEM_TO_BYTES (pc));
+  memcpy (newexp->elts + pc + 7, exp->elts + pc + oplen,
+         EXP_ELEM_TO_BYTES (exp->nelts - pc - oplen));
+
+  newexp->elts[pc].opcode = newexp->elts[pc + 2].opcode = OP_FUNCALL;
+  newexp->elts[pc + 1].longconst = (LONGEST) nargs;
+
+  newexp->elts[pc + 3].opcode = newexp->elts[pc + 6].opcode = OP_VAR_VALUE;
+  newexp->elts[pc + 4].block = block;
+  newexp->elts[pc + 5].symbol = sym;
+
+  *expp = newexp;
+  xfree (exp);
+}
+
+/* Type-class predicates */
+
+/* True iff TYPE is numeric (i.e., an INT, RANGE (of numeric type), or */
+/* FLOAT.) */
+
+static int
+numeric_type_p (struct type *type)
+{
+  if (type == NULL)
+    return 0;
+  else
+    {
+      switch (TYPE_CODE (type))
+       {
+       case TYPE_CODE_INT:
+       case TYPE_CODE_FLT:
+         return 1;
+       case TYPE_CODE_RANGE:
+         return (type == TYPE_TARGET_TYPE (type)
+                 || numeric_type_p (TYPE_TARGET_TYPE (type)));
+       default:
+         return 0;
+       }
+    }
+}
+
+/* True iff TYPE is integral (an INT or RANGE of INTs). */
+
+static int
+integer_type_p (struct type *type)
+{
+  if (type == NULL)
+    return 0;
+  else
+    {
+      switch (TYPE_CODE (type))
+       {
+       case TYPE_CODE_INT:
+         return 1;
+       case TYPE_CODE_RANGE:
+         return (type == TYPE_TARGET_TYPE (type)
+                 || integer_type_p (TYPE_TARGET_TYPE (type)));
+       default:
+         return 0;
+       }
+    }
+}
+
+/* True iff TYPE is scalar (INT, RANGE, FLOAT, ENUM). */
+
+static int
+scalar_type_p (struct type *type)
+{
+  if (type == NULL)
+    return 0;
+  else
+    {
+      switch (TYPE_CODE (type))
+       {
+       case TYPE_CODE_INT:
+       case TYPE_CODE_RANGE:
+       case TYPE_CODE_ENUM:
+       case TYPE_CODE_FLT:
+         return 1;
+       default:
+         return 0;
+       }
+    }
+}
+
+/* True iff TYPE is discrete (INT, RANGE, ENUM). */
+
+static int
+discrete_type_p (struct type *type)
+{
+  if (type == NULL)
+    return 0;
+  else
+    {
+      switch (TYPE_CODE (type))
+       {
+       case TYPE_CODE_INT:
+       case TYPE_CODE_RANGE:
+       case TYPE_CODE_ENUM:
+         return 1;
+       default:
+         return 0;
+       }
+    }
+}
+
+/* Returns non-zero if OP with operatands in the vector ARGS could be
+   a user-defined function. Errs on the side of pre-defined operators
+   (i.e., result 0). */
+
+static int
+possible_user_operator_p (enum exp_opcode op, struct value *args[])
+{
+  struct type *type0 = check_typedef (VALUE_TYPE (args[0]));
+  struct type *type1 =
+    (args[1] == NULL) ? NULL : check_typedef (VALUE_TYPE (args[1]));
+
+  switch (op)
+    {
+    default:
+      return 0;
+
+    case BINOP_ADD:
+    case BINOP_SUB:
+    case BINOP_MUL:
+    case BINOP_DIV:
+      return (!(numeric_type_p (type0) && numeric_type_p (type1)));
+
+    case BINOP_REM:
+    case BINOP_MOD:
+    case BINOP_BITWISE_AND:
+    case BINOP_BITWISE_IOR:
+    case BINOP_BITWISE_XOR:
+      return (!(integer_type_p (type0) && integer_type_p (type1)));
+
+    case BINOP_EQUAL:
+    case BINOP_NOTEQUAL:
+    case BINOP_LESS:
+    case BINOP_GTR:
+    case BINOP_LEQ:
+    case BINOP_GEQ:
+      return (!(scalar_type_p (type0) && scalar_type_p (type1)));
+
+    case BINOP_CONCAT:
+      return ((TYPE_CODE (type0) != TYPE_CODE_ARRAY &&
+              (TYPE_CODE (type0) != TYPE_CODE_PTR ||
+               TYPE_CODE (TYPE_TARGET_TYPE (type0))
+               != TYPE_CODE_ARRAY))
+             || (TYPE_CODE (type1) != TYPE_CODE_ARRAY &&
+                 (TYPE_CODE (type1) != TYPE_CODE_PTR ||
+                  TYPE_CODE (TYPE_TARGET_TYPE (type1)) != TYPE_CODE_ARRAY)));
+
+    case BINOP_EXP:
+      return (!(numeric_type_p (type0) && integer_type_p (type1)));
+
+    case UNOP_NEG:
+    case UNOP_PLUS:
+    case UNOP_LOGICAL_NOT:
+    case UNOP_ABS:
+      return (!numeric_type_p (type0));
+
+    }
+}
+\f
+                               /* Renaming */
+
+/** NOTE: In the following, we assume that a renaming type's name may
+ *  have an ___XD suffix.  It would be nice if this went away at some
+ *  point. */
+
+/* If TYPE encodes a renaming, returns the renaming suffix, which
+ * is XR for an object renaming, XRP for a procedure renaming, XRE for
+ * an exception renaming, and XRS for a subprogram renaming.  Returns
+ * NULL if NAME encodes none of these. */
+const char *
+ada_renaming_type (struct type *type)
+{
+  if (type != NULL && TYPE_CODE (type) == TYPE_CODE_ENUM)
+    {
+      const char *name = type_name_no_tag (type);
+      const char *suffix = (name == NULL) ? NULL : strstr (name, "___XR");
+      if (suffix == NULL
+         || (suffix[5] != '\000' && strchr ("PES_", suffix[5]) == NULL))
+       return NULL;
+      else
+       return suffix + 3;
+    }
+  else
+    return NULL;
+}
+
+/* Return non-zero iff SYM encodes an object renaming. */
+int
+ada_is_object_renaming (struct symbol *sym)
+{
+  const char *renaming_type = ada_renaming_type (SYMBOL_TYPE (sym));
+  return renaming_type != NULL
+    && (renaming_type[2] == '\0' || renaming_type[2] == '_');
+}
+
+/* Assuming that SYM encodes a non-object renaming, returns the original
+ * name of the renamed entity.   The name is good until the end of
+ * parsing. */
+const char *
+ada_simple_renamed_entity (struct symbol *sym)
+{
+  struct type *type;
+  const char *raw_name;
+  int len;
+  char *result;
+
+  type = SYMBOL_TYPE (sym);
+  if (type == NULL || TYPE_NFIELDS (type) < 1)
+    error ("Improperly encoded renaming.");
+
+  raw_name = TYPE_FIELD_NAME (type, 0);
+  len = (raw_name == NULL ? 0 : strlen (raw_name)) - 5;
+  if (len <= 0)
+    error ("Improperly encoded renaming.");
+
+  result = xmalloc (len + 1);
+  /* FIXME: add_name_string_cleanup should be defined in parse.c */
+  /*  add_name_string_cleanup (result); */
+  strncpy (result, raw_name, len);
+  result[len] = '\000';
+  return result;
+}
+\f
+
+                               /* Evaluation: Function Calls */
+
+/* Copy VAL onto the stack, using and updating *SP as the stack 
+   pointer. Return VAL as an lvalue. */
+
+static struct value *
+place_on_stack (struct value *val, CORE_ADDR *sp)
+{
+  CORE_ADDR old_sp = *sp;
+
+#ifdef STACK_ALIGN
+  *sp = push_bytes (*sp, VALUE_CONTENTS_RAW (val),
+                   STACK_ALIGN (TYPE_LENGTH
+                                (check_typedef (VALUE_TYPE (val)))));
+#else
+  *sp = push_bytes (*sp, VALUE_CONTENTS_RAW (val),
+                   TYPE_LENGTH (check_typedef (VALUE_TYPE (val))));
+#endif
+
+  VALUE_LVAL (val) = lval_memory;
+  if (INNER_THAN (1, 2))
+    VALUE_ADDRESS (val) = *sp;
+  else
+    VALUE_ADDRESS (val) = old_sp;
+
+  return val;
+}
+
+/* Return the value ACTUAL, converted to be an appropriate value for a
+   formal of type FORMAL_TYPE.  Use *SP as a stack pointer for
+   allocating any necessary descriptors (fat pointers), or copies of
+   values not residing in memory, updating it as needed. */
+
+static struct value *
+convert_actual (struct value *actual, struct type *formal_type0,
+               CORE_ADDR *sp)
+{
+  struct type *actual_type = check_typedef (VALUE_TYPE (actual));
+  struct type *formal_type = check_typedef (formal_type0);
+  struct type *formal_target =
+    TYPE_CODE (formal_type) == TYPE_CODE_PTR
+    ? check_typedef (TYPE_TARGET_TYPE (formal_type)) : formal_type;
+  struct type *actual_target =
+    TYPE_CODE (actual_type) == TYPE_CODE_PTR
+    ? check_typedef (TYPE_TARGET_TYPE (actual_type)) : actual_type;
+
+  if (ada_is_array_descriptor (formal_target)
+      && TYPE_CODE (actual_target) == TYPE_CODE_ARRAY)
+    return make_array_descriptor (formal_type, actual, sp);
+  else if (TYPE_CODE (formal_type) == TYPE_CODE_PTR)
+    {
+      if (TYPE_CODE (formal_target) == TYPE_CODE_ARRAY
+         && ada_is_array_descriptor (actual_target))
+       return desc_data (actual);
+      else if (TYPE_CODE (actual_type) != TYPE_CODE_PTR)
+       {
+         if (VALUE_LVAL (actual) != lval_memory)
+           {
+             struct value *val;
+             actual_type = check_typedef (VALUE_TYPE (actual));
+             val = allocate_value (actual_type);
+             memcpy ((char *) VALUE_CONTENTS_RAW (val),
+                     (char *) VALUE_CONTENTS (actual),
+                     TYPE_LENGTH (actual_type));
+             actual = place_on_stack (val, sp);
+           }
+         return value_addr (actual);
+       }
+    }
+  else if (TYPE_CODE (actual_type) == TYPE_CODE_PTR)
+    return ada_value_ind (actual);
+
+  return actual;
+}
+
+
+/* Push a descriptor of type TYPE for array value ARR on the stack at 
+   *SP, updating *SP to reflect the new descriptor.  Return either 
+   an lvalue representing the new descriptor, or (if TYPE is a pointer-
+   to-descriptor type rather than a descriptor type), a struct value*
+   representing a pointer to this descriptor. */
+
+static struct value *
+make_array_descriptor (struct type *type, struct value *arr, CORE_ADDR *sp)
+{
+  struct type *bounds_type = desc_bounds_type (type);
+  struct type *desc_type = desc_base_type (type);
+  struct value *descriptor = allocate_value (desc_type);
+  struct value *bounds = allocate_value (bounds_type);
+  CORE_ADDR bounds_addr;
+  int i;
+
+  for (i = ada_array_arity (check_typedef (VALUE_TYPE (arr))); i > 0; i -= 1)
+    {
+      modify_general_field (VALUE_CONTENTS (bounds),
+                           value_as_long (ada_array_bound (arr, i, 0)),
+                           desc_bound_bitpos (bounds_type, i, 0),
+                           desc_bound_bitsize (bounds_type, i, 0));
+      modify_general_field (VALUE_CONTENTS (bounds),
+                           value_as_long (ada_array_bound (arr, i, 1)),
+                           desc_bound_bitpos (bounds_type, i, 1),
+                           desc_bound_bitsize (bounds_type, i, 1));
+    }
+
+  bounds = place_on_stack (bounds, sp);
+
+  modify_general_field (VALUE_CONTENTS (descriptor),
+                       arr,
+                       fat_pntr_data_bitpos (desc_type),
+                       fat_pntr_data_bitsize (desc_type));
+  modify_general_field (VALUE_CONTENTS (descriptor),
+                       VALUE_ADDRESS (bounds),
+                       fat_pntr_bounds_bitpos (desc_type),
+                       fat_pntr_bounds_bitsize (desc_type));
+
+  descriptor = place_on_stack (descriptor, sp);
+
+  if (TYPE_CODE (type) == TYPE_CODE_PTR)
+    return value_addr (descriptor);
+  else
+    return descriptor;
+}
+
+
+/* Assuming a dummy frame has been established on the target, perform any 
+   conversions needed for calling function FUNC on the NARGS actual
+   parameters in ARGS, other than standard C conversions.   Does
+   nothing if FUNC does not have Ada-style prototype data, or if NARGS
+   does not match the number of arguments expected.   Use *SP as a
+   stack pointer for additional data that must be pushed, updating its
+   value as needed. */
+
+void
+ada_convert_actuals (struct value *func, int nargs, struct value *args[],
+                    CORE_ADDR *sp)
+{
+  int i;
+
+  if (TYPE_NFIELDS (VALUE_TYPE (func)) == 0
+      || nargs != TYPE_NFIELDS (VALUE_TYPE (func)))
+    return;
+
+  for (i = 0; i < nargs; i += 1)
+    args[i] =
+      convert_actual (args[i], TYPE_FIELD_TYPE (VALUE_TYPE (func), i), sp);
+}
+\f
+
+                               /* Symbol Lookup */
+
+
+/* The vectors of symbols and blocks ultimately returned from */
+/* ada_lookup_symbol_list. */
+
+/* Current size of defn_symbols and defn_blocks */
+static size_t defn_vector_size = 0;
+
+/* Current number of symbols found. */
+static int ndefns = 0;
+
+static struct symbol **defn_symbols = NULL;
+static struct block **defn_blocks = NULL;
+
+/* Return the result of a standard (literal, C-like) lookup of NAME in 
+ * given NAMESPACE. */
+
+static struct symbol *
+standard_lookup (const char *name, namespace_enum namespace)
+{
+  struct symbol *sym;
+  struct symtab *symtab;
+  sym = lookup_symbol (name, (struct block *) NULL, namespace, 0, &symtab);
+  return sym;
+}
+
+
+/* Non-zero iff there is at least one non-function/non-enumeral symbol */
+/* in SYMS[0..N-1].  We treat enumerals as functions, since they */
+/* contend in overloading in the same way. */
+static int
+is_nonfunction (struct symbol *syms[], int n)
+{
+  int i;
+
+  for (i = 0; i < n; i += 1)
+    if (TYPE_CODE (SYMBOL_TYPE (syms[i])) != TYPE_CODE_FUNC
+       && TYPE_CODE (SYMBOL_TYPE (syms[i])) != TYPE_CODE_ENUM)
+      return 1;
+
+  return 0;
+}
+
+/* If true (non-zero), then TYPE0 and TYPE1 represent equivalent
+   struct types.  Otherwise, they may not. */
+
+static int
+equiv_types (struct type *type0, struct type *type1)
+{
+  if (type0 == type1)
+    return 1;
+  if (type0 == NULL || type1 == NULL
+      || TYPE_CODE (type0) != TYPE_CODE (type1))
+    return 0;
+  if ((TYPE_CODE (type0) == TYPE_CODE_STRUCT
+       || TYPE_CODE (type0) == TYPE_CODE_ENUM)
+      && ada_type_name (type0) != NULL && ada_type_name (type1) != NULL
+      && STREQ (ada_type_name (type0), ada_type_name (type1)))
+    return 1;
+
+  return 0;
+}
+
+/* True iff SYM0 represents the same entity as SYM1, or one that is
+   no more defined than that of SYM1. */
+
+static int
+lesseq_defined_than (struct symbol *sym0, struct symbol *sym1)
+{
+  if (sym0 == sym1)
+    return 1;
+  if (SYMBOL_NAMESPACE (sym0) != SYMBOL_NAMESPACE (sym1)
+      || SYMBOL_CLASS (sym0) != SYMBOL_CLASS (sym1))
+    return 0;
+
+  switch (SYMBOL_CLASS (sym0))
+    {
+    case LOC_UNDEF:
+      return 1;
+    case LOC_TYPEDEF:
+      {
+       struct type *type0 = SYMBOL_TYPE (sym0);
+       struct type *type1 = SYMBOL_TYPE (sym1);
+       char *name0 = SYMBOL_NAME (sym0);
+       char *name1 = SYMBOL_NAME (sym1);
+       int len0 = strlen (name0);
+       return
+         TYPE_CODE (type0) == TYPE_CODE (type1)
+         && (equiv_types (type0, type1)
+             || (len0 < strlen (name1) && STREQN (name0, name1, len0)
+                 && STREQN (name1 + len0, "___XV", 5)));
+      }
+    case LOC_CONST:
+      return SYMBOL_VALUE (sym0) == SYMBOL_VALUE (sym1)
+       && equiv_types (SYMBOL_TYPE (sym0), SYMBOL_TYPE (sym1));
+    default:
+      return 0;
+    }
+}
+
+/* Append SYM to the end of defn_symbols, and BLOCK to the end of
+   defn_blocks, updating ndefns, and expanding defn_symbols and
+   defn_blocks as needed.   Do not include SYM if it is a duplicate.  */
+
+static void
+add_defn_to_vec (struct symbol *sym, struct block *block)
+{
+  int i;
+  size_t tmp;
+
+  if (SYMBOL_TYPE (sym) != NULL)
+    CHECK_TYPEDEF (SYMBOL_TYPE (sym));
+  for (i = 0; i < ndefns; i += 1)
+    {
+      if (lesseq_defined_than (sym, defn_symbols[i]))
+       return;
+      else if (lesseq_defined_than (defn_symbols[i], sym))
+       {
+         defn_symbols[i] = sym;
+         defn_blocks[i] = block;
+         return;
+       }
+    }
+
+  tmp = defn_vector_size;
+  GROW_VECT (defn_symbols, tmp, ndefns + 2);
+  GROW_VECT (defn_blocks, defn_vector_size, ndefns + 2);
+
+  defn_symbols[ndefns] = sym;
+  defn_blocks[ndefns] = block;
+  ndefns += 1;
+}
+
+/* Look, in partial_symtab PST, for symbol NAME in given namespace.
+   Check the global symbols if GLOBAL, the static symbols if not.  Do
+   wild-card match if WILD. */
+
+static struct partial_symbol *
+ada_lookup_partial_symbol (struct partial_symtab *pst, const char *name,
+                          int global, namespace_enum namespace, int wild)
+{
+  struct partial_symbol **start;
+  int name_len = strlen (name);
+  int length = (global ? pst->n_global_syms : pst->n_static_syms);
+  int i;
+
+  if (length == 0)
+    {
+      return (NULL);
+    }
+
+  start = (global ?
+          pst->objfile->global_psymbols.list + pst->globals_offset :
+          pst->objfile->static_psymbols.list + pst->statics_offset);
+
+  if (wild)
+    {
+      for (i = 0; i < length; i += 1)
+       {
+         struct partial_symbol *psym = start[i];
+
+         if (SYMBOL_NAMESPACE (psym) == namespace &&
+             wild_match (name, name_len, SYMBOL_NAME (psym)))
+           return psym;
+       }
+      return NULL;
+    }
+  else
+    {
+      if (global)
+       {
+         int U;
+         i = 0;
+         U = length - 1;
+         while (U - i > 4)
+           {
+             int M = (U + i) >> 1;
+             struct partial_symbol *psym = start[M];
+             if (SYMBOL_NAME (psym)[0] < name[0])
+               i = M + 1;
+             else if (SYMBOL_NAME (psym)[0] > name[0])
+               U = M - 1;
+             else if (strcmp (SYMBOL_NAME (psym), name) < 0)
+               i = M + 1;
+             else
+               U = M;
+           }
+       }
+      else
+       i = 0;
+
+      while (i < length)
+       {
+         struct partial_symbol *psym = start[i];
+
+         if (SYMBOL_NAMESPACE (psym) == namespace)
+           {
+             int cmp = strncmp (name, SYMBOL_NAME (psym), name_len);
+
+             if (cmp < 0)
+               {
+                 if (global)
+                   break;
+               }
+             else if (cmp == 0
+                      && is_name_suffix (SYMBOL_NAME (psym) + name_len))
+               return psym;
+           }
+         i += 1;
+       }
+
+      if (global)
+       {
+         int U;
+         i = 0;
+         U = length - 1;
+         while (U - i > 4)
+           {
+             int M = (U + i) >> 1;
+             struct partial_symbol *psym = start[M];
+             if (SYMBOL_NAME (psym)[0] < '_')
+               i = M + 1;
+             else if (SYMBOL_NAME (psym)[0] > '_')
+               U = M - 1;
+             else if (strcmp (SYMBOL_NAME (psym), "_ada_") < 0)
+               i = M + 1;
+             else
+               U = M;
+           }
+       }
+      else
+       i = 0;
+
+      while (i < length)
+       {
+         struct partial_symbol *psym = start[i];
+
+         if (SYMBOL_NAMESPACE (psym) == namespace)
+           {
+             int cmp;
+
+             cmp = (int) '_' - (int) SYMBOL_NAME (psym)[0];
+             if (cmp == 0)
+               {
+                 cmp = strncmp ("_ada_", SYMBOL_NAME (psym), 5);
+                 if (cmp == 0)
+                   cmp = strncmp (name, SYMBOL_NAME (psym) + 5, name_len);
+               }
+
+             if (cmp < 0)
+               {
+                 if (global)
+                   break;
+               }
+             else if (cmp == 0
+                      && is_name_suffix (SYMBOL_NAME (psym) + name_len + 5))
+               return psym;
+           }
+         i += 1;
+       }
+
+    }
+  return NULL;
+}
+
+
+/* Find a symbol table containing symbol SYM or NULL if none.  */
+static struct symtab *
+symtab_for_sym (struct symbol *sym)
+{
+  struct symtab *s;
+  struct objfile *objfile;
+  struct block *b;
+  struct symbol *tmp_sym;
+  int i, j;
+
+  ALL_SYMTABS (objfile, s)
+  {
+    switch (SYMBOL_CLASS (sym))
+      {
+      case LOC_CONST:
+      case LOC_STATIC:
+      case LOC_TYPEDEF:
+      case LOC_REGISTER:
+      case LOC_LABEL:
+      case LOC_BLOCK:
+      case LOC_CONST_BYTES:
+       b = BLOCKVECTOR_BLOCK (BLOCKVECTOR (s), GLOBAL_BLOCK);
+       ALL_BLOCK_SYMBOLS (b, i, tmp_sym) if (sym == tmp_sym)
+         return s;
+       b = BLOCKVECTOR_BLOCK (BLOCKVECTOR (s), STATIC_BLOCK);
+       ALL_BLOCK_SYMBOLS (b, i, tmp_sym) if (sym == tmp_sym)
+         return s;
+       break;
+      default:
+       break;
+      }
+    switch (SYMBOL_CLASS (sym))
+      {
+      case LOC_REGISTER:
+      case LOC_ARG:
+      case LOC_REF_ARG:
+      case LOC_REGPARM:
+      case LOC_REGPARM_ADDR:
+      case LOC_LOCAL:
+      case LOC_TYPEDEF:
+      case LOC_LOCAL_ARG:
+      case LOC_BASEREG:
+      case LOC_BASEREG_ARG:
+       for (j = FIRST_LOCAL_BLOCK;
+            j < BLOCKVECTOR_NBLOCKS (BLOCKVECTOR (s)); j += 1)
+         {
+           b = BLOCKVECTOR_BLOCK (BLOCKVECTOR (s), j);
+           ALL_BLOCK_SYMBOLS (b, i, tmp_sym) if (sym == tmp_sym)
+             return s;
+         }
+       break;
+      default:
+       break;
+      }
+  }
+  return NULL;
+}
+
+/* Return a minimal symbol matching NAME according to Ada demangling 
+   rules. Returns NULL if there is no such minimal symbol. */
+
+struct minimal_symbol *
+ada_lookup_minimal_symbol (const char *name)
+{
+  struct objfile *objfile;
+  struct minimal_symbol *msymbol;
+  int wild_match = (strstr (name, "__") == NULL);
+
+  ALL_MSYMBOLS (objfile, msymbol)
+  {
+    if (ada_match_name (SYMBOL_NAME (msymbol), name, wild_match)
+       && MSYMBOL_TYPE (msymbol) != mst_solib_trampoline)
+      return msymbol;
+  }
+
+  return NULL;
+}
+
+/* For all subprograms that statically enclose the subprogram of the
+ * selected frame, add symbols matching identifier NAME in NAMESPACE
+ * and their blocks to vectors *defn_symbols and *defn_blocks, as for
+ * ada_add_block_symbols (q.v.).   If WILD, treat as NAME with a
+ * wildcard prefix.  At the moment, this function uses a heuristic to
+ * find the frames of enclosing subprograms: it treats the
+ * pointer-sized value at location 0 from the local-variable base of a
+ * frame as a static link, and then searches up the call stack for a
+ * frame with that same local-variable base. */
+static void
+add_symbols_from_enclosing_procs (const char *name, namespace_enum namespace,
+                                 int wild_match)
+{
+#ifdef i386
+  static struct symbol static_link_sym;
+  static struct symbol *static_link;
+
+  struct cleanup *old_chain = make_cleanup (null_cleanup, NULL);
+  struct frame_info *frame;
+  struct frame_info *target_frame;
+
+  if (static_link == NULL)
+    {
+      /* Initialize the local variable symbol that stands for the
+       * static link (when it exists). */
+      static_link = &static_link_sym;
+      SYMBOL_NAME (static_link) = "";
+      SYMBOL_LANGUAGE (static_link) = language_unknown;
+      SYMBOL_CLASS (static_link) = LOC_LOCAL;
+      SYMBOL_NAMESPACE (static_link) = VAR_NAMESPACE;
+      SYMBOL_TYPE (static_link) = lookup_pointer_type (builtin_type_void);
+      SYMBOL_VALUE (static_link) =
+       -(long) TYPE_LENGTH (SYMBOL_TYPE (static_link));
+    }
+
+  frame = selected_frame;
+  while (frame != NULL && ndefns == 0)
+    {
+      struct block *block;
+      struct value *target_link_val = read_var_value (static_link, frame);
+      CORE_ADDR target_link;
+
+      if (target_link_val == NULL)
+       break;
+      QUIT;
+
+      target_link = target_link_val;
+      do
+       {
+         QUIT;
+         frame = get_prev_frame (frame);
+       }
+      while (frame != NULL && FRAME_LOCALS_ADDRESS (frame) != target_link);
+
+      if (frame == NULL)
+       break;
+
+      block = get_frame_block (frame, 0);
+      while (block != NULL && block_function (block) != NULL && ndefns == 0)
+       {
+         ada_add_block_symbols (block, name, namespace, NULL, wild_match);
+
+         block = BLOCK_SUPERBLOCK (block);
+       }
+    }
+
+  do_cleanups (old_chain);
+#endif
+}
+
+/* True if TYPE is definitely an artificial type supplied to a symbol
+ * for which no debugging information was given in the symbol file. */
+static int
+is_nondebugging_type (struct type *type)
+{
+  char *name = ada_type_name (type);
+  return (name != NULL && STREQ (name, "<variable, no debug info>"));
+}
+
+/* Remove any non-debugging symbols in SYMS[0 .. NSYMS-1] that definitely 
+ * duplicate other symbols in the list.  (The only case I know of where
+ * this happens is when object files containing stabs-in-ecoff are
+ * linked with files containing ordinary ecoff debugging symbols (or no
+ * debugging symbols)). Modifies SYMS to squeeze out deleted symbols,
+ * and applies the same modification to BLOCKS to maintain the
+ * correspondence between SYMS[i] and BLOCKS[i].  Returns the number
+ * of symbols in the modified list. */
+static int
+remove_extra_symbols (struct symbol **syms, struct block **blocks, int nsyms)
+{
+  int i, j;
+
+  i = 0;
+  while (i < nsyms)
+    {
+      if (SYMBOL_NAME (syms[i]) != NULL
+         && SYMBOL_CLASS (syms[i]) == LOC_STATIC
+         && is_nondebugging_type (SYMBOL_TYPE (syms[i])))
+       {
+         for (j = 0; j < nsyms; j += 1)
+           {
+             if (i != j
+                 && SYMBOL_NAME (syms[j]) != NULL
+                 && STREQ (SYMBOL_NAME (syms[i]), SYMBOL_NAME (syms[j]))
+                 && SYMBOL_CLASS (syms[i]) == SYMBOL_CLASS (syms[j])
+                 && SYMBOL_VALUE_ADDRESS (syms[i])
+                 == SYMBOL_VALUE_ADDRESS (syms[j]))
+               {
+                 int k;
+                 for (k = i + 1; k < nsyms; k += 1)
+                   {
+                     syms[k - 1] = syms[k];
+                     blocks[k - 1] = blocks[k];
+                   }
+                 nsyms -= 1;
+                 goto NextSymbol;
+               }
+           }
+       }
+      i += 1;
+    NextSymbol:
+      ;
+    }
+  return nsyms;
+}
+
+/* Find symbols in NAMESPACE matching NAME, in BLOCK0 and enclosing 
+   scope and in global scopes, returning the number of matches.  Sets 
+   *SYMS to point to a vector of matching symbols, with *BLOCKS
+   pointing to the vector of corresponding blocks in which those
+   symbols reside.  These two vectors are transient---good only to the
+   next call of ada_lookup_symbol_list.  Any non-function/non-enumeral symbol
+   match within the nest of blocks whose innermost member is BLOCK0,
+   is the outermost match returned (no other matches in that or
+   enclosing blocks is returned).  If there are any matches in or
+   surrounding BLOCK0, then these alone are returned. */
+
+int
+ada_lookup_symbol_list (const char *name, struct block *block0,
+                       namespace_enum namespace, struct symbol ***syms,
+                       struct block ***blocks)
+{
+  struct symbol *sym;
+  struct symtab *s;
+  struct partial_symtab *ps;
+  struct blockvector *bv;
+  struct objfile *objfile;
+  struct block *b;
+  struct block *block;
+  struct minimal_symbol *msymbol;
+  int wild_match = (strstr (name, "__") == NULL);
+  int cacheIfUnique;
+
+#ifdef TIMING
+  markTimeStart (0);
+#endif
+
+  ndefns = 0;
+  cacheIfUnique = 0;
+
+  /* Search specified block and its superiors.  */
+
+  block = block0;
+  while (block != NULL)
+    {
+      ada_add_block_symbols (block, name, namespace, NULL, wild_match);
+
+      /* If we found a non-function match, assume that's the one. */
+      if (is_nonfunction (defn_symbols, ndefns))
+       goto done;
+
+      block = BLOCK_SUPERBLOCK (block);
+    }
+
+  /* If we found ANY matches in the specified BLOCK, we're done. */
+
+  if (ndefns > 0)
+    goto done;
+
+  cacheIfUnique = 1;
+
+  /* Now add symbols from all global blocks: symbol tables, minimal symbol
+     tables, and psymtab's */
+
+  ALL_SYMTABS (objfile, s)
+  {
+    QUIT;
+    if (!s->primary)
+      continue;
+    bv = BLOCKVECTOR (s);
+    block = BLOCKVECTOR_BLOCK (bv, GLOBAL_BLOCK);
+    ada_add_block_symbols (block, name, namespace, objfile, wild_match);
+  }
+
+  if (namespace == VAR_NAMESPACE)
+    {
+      ALL_MSYMBOLS (objfile, msymbol)
+      {
+       if (ada_match_name (SYMBOL_NAME (msymbol), name, wild_match))
+         {
+           switch (MSYMBOL_TYPE (msymbol))
+             {
+             case mst_solib_trampoline:
+               break;
+             default:
+               s = find_pc_symtab (SYMBOL_VALUE_ADDRESS (msymbol));
+               if (s != NULL)
+                 {
+                   int old_ndefns = ndefns;
+                   QUIT;
+                   bv = BLOCKVECTOR (s);
+                   block = BLOCKVECTOR_BLOCK (bv, GLOBAL_BLOCK);
+                   ada_add_block_symbols (block,
+                                          SYMBOL_NAME (msymbol),
+                                          namespace, objfile, wild_match);
+                   if (ndefns == old_ndefns)
+                     {
+                       block = BLOCKVECTOR_BLOCK (bv, STATIC_BLOCK);
+                       ada_add_block_symbols (block,
+                                              SYMBOL_NAME (msymbol),
+                                              namespace, objfile,
+                                              wild_match);
+                     }
+                 }
+             }
+         }
+      }
+    }
+
+  ALL_PSYMTABS (objfile, ps)
+  {
+    QUIT;
+    if (!ps->readin
+       && ada_lookup_partial_symbol (ps, name, 1, namespace, wild_match))
+      {
+       s = PSYMTAB_TO_SYMTAB (ps);
+       if (!s->primary)
+         continue;
+       bv = BLOCKVECTOR (s);
+       block = BLOCKVECTOR_BLOCK (bv, GLOBAL_BLOCK);
+       ada_add_block_symbols (block, name, namespace, objfile, wild_match);
+      }
+  }
+
+  /* Now add symbols from all per-file blocks if we've gotten no hits.  
+     (Not strictly correct, but perhaps better than an error).
+     Do the symtabs first, then check the psymtabs */
+
+  if (ndefns == 0)
+    {
+
+      ALL_SYMTABS (objfile, s)
+      {
+       QUIT;
+       if (!s->primary)
+         continue;
+       bv = BLOCKVECTOR (s);
+       block = BLOCKVECTOR_BLOCK (bv, STATIC_BLOCK);
+       ada_add_block_symbols (block, name, namespace, objfile, wild_match);
+      }
+
+      ALL_PSYMTABS (objfile, ps)
+      {
+       QUIT;
+       if (!ps->readin
+           && ada_lookup_partial_symbol (ps, name, 0, namespace, wild_match))
+         {
+           s = PSYMTAB_TO_SYMTAB (ps);
+           bv = BLOCKVECTOR (s);
+           if (!s->primary)
+             continue;
+           block = BLOCKVECTOR_BLOCK (bv, STATIC_BLOCK);
+           ada_add_block_symbols (block, name, namespace,
+                                  objfile, wild_match);
+         }
+      }
+    }
+
+  /* Finally, we try to find NAME as a local symbol in some lexically
+     enclosing block.  We do this last, expecting this case to be
+     rare. */
+  if (ndefns == 0)
+    {
+      add_symbols_from_enclosing_procs (name, namespace, wild_match);
+      if (ndefns > 0)
+       goto done;
+    }
+
+done:
+  ndefns = remove_extra_symbols (defn_symbols, defn_blocks, ndefns);
+
+
+  *syms = defn_symbols;
+  *blocks = defn_blocks;
+#ifdef TIMING
+  markTimeStop (0);
+#endif
+  return ndefns;
+}
+
+/* Return a symbol in NAMESPACE matching NAME, in BLOCK0 and enclosing 
+ * scope and in global scopes, or NULL if none.  NAME is folded to
+ * lower case first, unless it is surrounded in single quotes. 
+ * Otherwise, the result is as for ada_lookup_symbol_list, but is 
+ * disambiguated by user query if needed. */
+
+struct symbol *
+ada_lookup_symbol (const char *name, struct block *block0,
+                  namespace_enum namespace)
+{
+  struct symbol **candidate_syms;
+  struct block **candidate_blocks;
+  int n_candidates;
+
+  n_candidates = ada_lookup_symbol_list (name,
+                                        block0, namespace,
+                                        &candidate_syms, &candidate_blocks);
+
+  if (n_candidates == 0)
+    return NULL;
+  else if (n_candidates != 1)
+    user_select_syms (candidate_syms, candidate_blocks, n_candidates, 1);
+
+  return candidate_syms[0];
+}
+
+
+/* True iff STR is a possible encoded suffix of a normal Ada name 
+ * that is to be ignored for matching purposes.  Suffixes of parallel
+ * names (e.g., XVE) are not included here.  Currently, the possible suffixes 
+ * are given by the regular expression:
+ *        (X[nb]*)?(__[0-9]+|\$[0-9]+|___(LJM|X([FDBUP].*|R[^T]?)))?$
+ * 
+ */
+static int
+is_name_suffix (const char *str)
+{
+  int k;
+  if (str[0] == 'X')
+    {
+      str += 1;
+      while (str[0] != '_' && str[0] != '\0')
+       {
+         if (str[0] != 'n' && str[0] != 'b')
+           return 0;
+         str += 1;
+       }
+    }
+  if (str[0] == '\000')
+    return 1;
+  if (str[0] == '_')
+    {
+      if (str[1] != '_' || str[2] == '\000')
+       return 0;
+      if (str[2] == '_')
+       {
+         if (STREQ (str + 3, "LJM"))
+           return 1;
+         if (str[3] != 'X')
+           return 0;
+         if (str[4] == 'F' || str[4] == 'D' || str[4] == 'B' ||
+             str[4] == 'U' || str[4] == 'P')
+           return 1;
+         if (str[4] == 'R' && str[5] != 'T')
+           return 1;
+         return 0;
+       }
+      for (k = 2; str[k] != '\0'; k += 1)
+       if (!isdigit (str[k]))
+         return 0;
+      return 1;
+    }
+  if (str[0] == '$' && str[1] != '\000')
+    {
+      for (k = 1; str[k] != '\0'; k += 1)
+       if (!isdigit (str[k]))
+         return 0;
+      return 1;
+    }
+  return 0;
+}
+
+/* True if NAME represents a name of the form A1.A2....An, n>=1 and 
+ * PATN[0..PATN_LEN-1] = Ak.Ak+1.....An for some k >= 1.  Ignores
+ * informational suffixes of NAME (i.e., for which is_name_suffix is
+ * true). */
+static int
+wild_match (const char *patn, int patn_len, const char *name)
+{
+  int name_len;
+  int s, e;
+
+  name_len = strlen (name);
+  if (name_len >= patn_len + 5 && STREQN (name, "_ada_", 5)
+      && STREQN (patn, name + 5, patn_len)
+      && is_name_suffix (name + patn_len + 5))
+    return 1;
+
+  while (name_len >= patn_len)
+    {
+      if (STREQN (patn, name, patn_len) && is_name_suffix (name + patn_len))
+       return 1;
+      do
+       {
+         name += 1;
+         name_len -= 1;
+       }
+      while (name_len > 0
+            && name[0] != '.' && (name[0] != '_' || name[1] != '_'));
+      if (name_len <= 0)
+       return 0;
+      if (name[0] == '_')
+       {
+         if (!islower (name[2]))
+           return 0;
+         name += 2;
+         name_len -= 2;
+       }
+      else
+       {
+         if (!islower (name[1]))
+           return 0;
+         name += 1;
+         name_len -= 1;
+       }
+    }
+
+  return 0;
+}
+
+
+/* Add symbols from BLOCK matching identifier NAME in NAMESPACE to 
+   vector *defn_symbols, updating *defn_symbols (if necessary), *SZ (the size of
+   the vector *defn_symbols), and *ndefns (the number of symbols
+   currently stored in *defn_symbols).  If WILD, treat as NAME with a
+   wildcard prefix. OBJFILE is the section containing BLOCK. */
+
+static void
+ada_add_block_symbols (struct block *block, const char *name,
+                      namespace_enum namespace, struct objfile *objfile,
+                      int wild)
+{
+  int i;
+  int name_len = strlen (name);
+  /* A matching argument symbol, if any. */
+  struct symbol *arg_sym;
+  /* Set true when we find a matching non-argument symbol */
+  int found_sym;
+  int is_sorted = BLOCK_SHOULD_SORT (block);
+  struct symbol *sym;
+
+  arg_sym = NULL;
+  found_sym = 0;
+  if (wild)
+    {
+      struct symbol *sym;
+      ALL_BLOCK_SYMBOLS (block, i, sym)
+      {
+       if (SYMBOL_NAMESPACE (sym) == namespace &&
+           wild_match (name, name_len, SYMBOL_NAME (sym)))
+         {
+           switch (SYMBOL_CLASS (sym))
+             {
+             case LOC_ARG:
+             case LOC_LOCAL_ARG:
+             case LOC_REF_ARG:
+             case LOC_REGPARM:
+             case LOC_REGPARM_ADDR:
+             case LOC_BASEREG_ARG:
+               arg_sym = sym;
+               break;
+             case LOC_UNRESOLVED:
+               continue;
+             default:
+               found_sym = 1;
+               fill_in_ada_prototype (sym);
+               add_defn_to_vec (fixup_symbol_section (sym, objfile), block);
+               break;
+             }
+         }
+      }
+    }
+  else
+    {
+      if (is_sorted)
+       {
+         int U;
+         i = 0;
+         U = BLOCK_NSYMS (block) - 1;
+         while (U - i > 4)
+           {
+             int M = (U + i) >> 1;
+             struct symbol *sym = BLOCK_SYM (block, M);
+             if (SYMBOL_NAME (sym)[0] < name[0])
+               i = M + 1;
+             else if (SYMBOL_NAME (sym)[0] > name[0])
+               U = M - 1;
+             else if (strcmp (SYMBOL_NAME (sym), name) < 0)
+               i = M + 1;
+             else
+               U = M;
+           }
+       }
+      else
+       i = 0;
+
+      for (; i < BLOCK_BUCKETS (block); i += 1)
+       for (sym = BLOCK_BUCKET (block, i); sym != NULL; sym = sym->hash_next)
+         {
+           if (SYMBOL_NAMESPACE (sym) == namespace)
+             {
+               int cmp = strncmp (name, SYMBOL_NAME (sym), name_len);
+
+               if (cmp < 0)
+                 {
+                   if (is_sorted)
+                     {
+                       i = BLOCK_BUCKETS (block);
+                       break;
+                     }
+                 }
+               else if (cmp == 0
+                        && is_name_suffix (SYMBOL_NAME (sym) + name_len))
+                 {
+                   switch (SYMBOL_CLASS (sym))
+                     {
+                     case LOC_ARG:
+                     case LOC_LOCAL_ARG:
+                     case LOC_REF_ARG:
+                     case LOC_REGPARM:
+                     case LOC_REGPARM_ADDR:
+                     case LOC_BASEREG_ARG:
+                       arg_sym = sym;
+                       break;
+                     case LOC_UNRESOLVED:
+                       break;
+                     default:
+                       found_sym = 1;
+                       fill_in_ada_prototype (sym);
+                       add_defn_to_vec (fixup_symbol_section (sym, objfile),
+                                        block);
+                       break;
+                     }
+                 }
+             }
+         }
+    }
+
+  if (!found_sym && arg_sym != NULL)
+    {
+      fill_in_ada_prototype (arg_sym);
+      add_defn_to_vec (fixup_symbol_section (arg_sym, objfile), block);
+    }
+
+  if (!wild)
+    {
+      arg_sym = NULL;
+      found_sym = 0;
+      if (is_sorted)
+       {
+         int U;
+         i = 0;
+         U = BLOCK_NSYMS (block) - 1;
+         while (U - i > 4)
+           {
+             int M = (U + i) >> 1;
+             struct symbol *sym = BLOCK_SYM (block, M);
+             if (SYMBOL_NAME (sym)[0] < '_')
+               i = M + 1;
+             else if (SYMBOL_NAME (sym)[0] > '_')
+               U = M - 1;
+             else if (strcmp (SYMBOL_NAME (sym), "_ada_") < 0)
+               i = M + 1;
+             else
+               U = M;
+           }
+       }
+      else
+       i = 0;
+
+      for (; i < BLOCK_BUCKETS (block); i += 1)
+       for (sym = BLOCK_BUCKET (block, i); sym != NULL; sym = sym->hash_next)
+         {
+           struct symbol *sym = BLOCK_SYM (block, i);
+
+           if (SYMBOL_NAMESPACE (sym) == namespace)
+             {
+               int cmp;
+
+               cmp = (int) '_' - (int) SYMBOL_NAME (sym)[0];
+               if (cmp == 0)
+                 {
+                   cmp = strncmp ("_ada_", SYMBOL_NAME (sym), 5);
+                   if (cmp == 0)
+                     cmp = strncmp (name, SYMBOL_NAME (sym) + 5, name_len);
+                 }
+
+               if (cmp < 0)
+                 {
+                   if (is_sorted)
+                     {
+                       i = BLOCK_BUCKETS (block);
+                       break;
+                     }
+                 }
+               else if (cmp == 0
+                        && is_name_suffix (SYMBOL_NAME (sym) + name_len + 5))
+                 {
+                   switch (SYMBOL_CLASS (sym))
+                     {
+                     case LOC_ARG:
+                     case LOC_LOCAL_ARG:
+                     case LOC_REF_ARG:
+                     case LOC_REGPARM:
+                     case LOC_REGPARM_ADDR:
+                     case LOC_BASEREG_ARG:
+                       arg_sym = sym;
+                       break;
+                     case LOC_UNRESOLVED:
+                       break;
+                     default:
+                       found_sym = 1;
+                       fill_in_ada_prototype (sym);
+                       add_defn_to_vec (fixup_symbol_section (sym, objfile),
+                                        block);
+                       break;
+                     }
+                 }
+             }
+         }
+
+      /* NOTE: This really shouldn't be needed for _ada_ symbols.
+         They aren't parameters, right? */
+      if (!found_sym && arg_sym != NULL)
+       {
+         fill_in_ada_prototype (arg_sym);
+         add_defn_to_vec (fixup_symbol_section (arg_sym, objfile), block);
+       }
+    }
+}
+\f
+
+                               /* Function Types */
+
+/* Assuming that SYM is the symbol for a function, fill in its type 
+   with prototype information, if it is not already there.  */
+
+static void
+fill_in_ada_prototype (struct symbol *func)
+{
+  struct block *b;
+  int nargs, nsyms;
+  int i;
+  struct type *ftype;
+  struct type *rtype;
+  size_t max_fields;
+  struct symbol *sym;
+
+  if (func == NULL
+      || TYPE_CODE (SYMBOL_TYPE (func)) != TYPE_CODE_FUNC
+      || TYPE_FIELDS (SYMBOL_TYPE (func)) != NULL)
+    return;
+
+  /* We make each function type unique, so that each may have its own */
+  /* parameter types.  This particular way of doing so wastes space: */
+  /* it would be nicer to build the argument types while the original */
+  /* function type is being built (FIXME). */
+  rtype = check_typedef (TYPE_TARGET_TYPE (SYMBOL_TYPE (func)));
+  ftype = alloc_type (TYPE_OBJFILE (SYMBOL_TYPE (func)));
+  make_function_type (rtype, &ftype);
+  SYMBOL_TYPE (func) = ftype;
+
+  b = SYMBOL_BLOCK_VALUE (func);
+
+  nargs = 0;
+  max_fields = 8;
+  TYPE_FIELDS (ftype) =
+    (struct field *) xmalloc (sizeof (struct field) * max_fields);
+  ALL_BLOCK_SYMBOLS (b, i, sym)
+  {
+    GROW_VECT (TYPE_FIELDS (ftype), max_fields, nargs + 1);
+
+    switch (SYMBOL_CLASS (sym))
+      {
+      case LOC_REF_ARG:
+      case LOC_REGPARM_ADDR:
+       TYPE_FIELD_BITPOS (ftype, nargs) = nargs;
+       TYPE_FIELD_BITSIZE (ftype, nargs) = 0;
+       TYPE_FIELD_TYPE (ftype, nargs) =
+         lookup_pointer_type (check_typedef (SYMBOL_TYPE (sym)));
+       TYPE_FIELD_NAME (ftype, nargs) = SYMBOL_NAME (sym);
+       nargs += 1;
+
+       break;
+
+      case LOC_ARG:
+      case LOC_REGPARM:
+      case LOC_LOCAL_ARG:
+      case LOC_BASEREG_ARG:
+       TYPE_FIELD_BITPOS (ftype, nargs) = nargs;
+       TYPE_FIELD_BITSIZE (ftype, nargs) = 0;
+       TYPE_FIELD_TYPE (ftype, nargs) = check_typedef (SYMBOL_TYPE (sym));
+       TYPE_FIELD_NAME (ftype, nargs) = SYMBOL_NAME (sym);
+       nargs += 1;
+
+       break;
+
+      default:
+       break;
+      }
+  }
+
+  /* Re-allocate fields vector; if there are no fields, make the */
+  /* fields pointer non-null anyway, to mark that this function type */
+  /* has been filled in. */
+
+  TYPE_NFIELDS (ftype) = nargs;
+  if (nargs == 0)
+    {
+      static struct field dummy_field = { 0, 0, 0, 0 };
+      xfree (TYPE_FIELDS (ftype));
+      TYPE_FIELDS (ftype) = &dummy_field;
+    }
+  else
+    {
+      struct field *fields =
+       (struct field *) TYPE_ALLOC (ftype, nargs * sizeof (struct field));
+      memcpy ((char *) fields,
+             (char *) TYPE_FIELDS (ftype), nargs * sizeof (struct field));
+      xfree (TYPE_FIELDS (ftype));
+      TYPE_FIELDS (ftype) = fields;
+    }
+}
+\f
+
+                               /* Breakpoint-related */
+
+char no_symtab_msg[] =
+  "No symbol table is loaded.  Use the \"file\" command.";
+
+/* Assuming that LINE is pointing at the beginning of an argument to
+   'break', return a pointer to the delimiter for the initial segment
+   of that name.  This is the first ':', ' ', or end of LINE. 
+*/
+char *
+ada_start_decode_line_1 (char *line)
+{
+  /* [NOTE: strpbrk would be more elegant, but I am reluctant to be
+     the first to use such a library function in GDB code.] */
+  char *p;
+  for (p = line; *p != '\000' && *p != ' ' && *p != ':'; p += 1)
+    ;
+  return p;
+}
+
+/* *SPEC points to a function and line number spec (as in a break
+   command), following any initial file name specification.
+
+   Return all symbol table/line specfications (sals) consistent with the
+   information in *SPEC and FILE_TABLE in the
+   following sense: 
+     + FILE_TABLE is null, or the sal refers to a line in the file
+       named by FILE_TABLE.
+     + If *SPEC points to an argument with a trailing ':LINENUM',
+       then the sal refers to that line (or one following it as closely as 
+       possible).
+     + If *SPEC does not start with '*', the sal is in a function with 
+       that name.
+
+   Returns with 0 elements if no matching non-minimal symbols found.
+
+   If *SPEC begins with a function name of the form <NAME>, then NAME
+   is taken as a literal name; otherwise the function name is subject
+   to the usual mangling.
+
+   *SPEC is updated to point after the function/line number specification.
+
+   FUNFIRSTLINE is non-zero if we desire the first line of real code
+   in each function (this is ignored in the presence of a LINENUM spec.).
+
+   If CANONICAL is non-NULL, and if any of the sals require a
+   'canonical line spec', then *CANONICAL is set to point to an array
+   of strings, corresponding to and equal in length to the returned
+   list of sals, such that (*CANONICAL)[i] is non-null and contains a 
+   canonical line spec for the ith returned sal, if needed.  If no 
+   canonical line specs are required and CANONICAL is non-null, 
+   *CANONICAL is set to NULL.
+
+   A 'canonical line spec' is simply a name (in the format of the
+   breakpoint command) that uniquely identifies a breakpoint position,
+   with no further contextual information or user selection.  It is
+   needed whenever the file name, function name, and line number
+   information supplied is insufficient for this unique
+   identification.  Currently overloaded functions, the name '*', 
+   or static functions without a filename yield a canonical line spec.
+   The array and the line spec strings are allocated on the heap; it
+   is the caller's responsibility to free them.   */
+
+struct symtabs_and_lines
+ada_finish_decode_line_1 (char **spec, struct symtab *file_table,
+                         int funfirstline, char ***canonical)
+{
+  struct symbol **symbols;
+  struct block **blocks;
+  struct block *block;
+  int n_matches, i, line_num;
+  struct symtabs_and_lines selected;
+  struct cleanup *old_chain = make_cleanup (null_cleanup, NULL);
+  char *name;
+
+  int len;
+  char *lower_name;
+  char *unquoted_name;
+
+  if (file_table == NULL)
+    block = get_selected_block (NULL);
+  else
+    block = BLOCKVECTOR_BLOCK (BLOCKVECTOR (file_table), STATIC_BLOCK);
+
+  if (canonical != NULL)
+    *canonical = (char **) NULL;
+
+  name = *spec;
+  if (**spec == '*')
+    *spec += 1;
+  else
+    {
+      while (**spec != '\000' &&
+            !strchr (ada_completer_word_break_characters, **spec))
+       *spec += 1;
+    }
+  len = *spec - name;
+
+  line_num = -1;
+  if (file_table != NULL && (*spec)[0] == ':' && isdigit ((*spec)[1]))
+    {
+      line_num = strtol (*spec + 1, spec, 10);
+      while (**spec == ' ' || **spec == '\t')
+       *spec += 1;
+    }
+
+  if (name[0] == '*')
+    {
+      if (line_num == -1)
+       error ("Wild-card function with no line number or file name.");
+
+      return all_sals_for_line (file_table->filename, line_num, canonical);
+    }
+
+  if (name[0] == '\'')
+    {
+      name += 1;
+      len -= 2;
+    }
+
+  if (name[0] == '<')
+    {
+      unquoted_name = (char *) alloca (len - 1);
+      memcpy (unquoted_name, name + 1, len - 2);
+      unquoted_name[len - 2] = '\000';
+      lower_name = NULL;
+    }
+  else
+    {
+      unquoted_name = (char *) alloca (len + 1);
+      memcpy (unquoted_name, name, len);
+      unquoted_name[len] = '\000';
+      lower_name = (char *) alloca (len + 1);
+      for (i = 0; i < len; i += 1)
+       lower_name[i] = tolower (name[i]);
+      lower_name[len] = '\000';
+    }
+
+  n_matches = 0;
+  if (lower_name != NULL)
+    n_matches = ada_lookup_symbol_list (ada_mangle (lower_name), block,
+                                       VAR_NAMESPACE, &symbols, &blocks);
+  if (n_matches == 0)
+    n_matches = ada_lookup_symbol_list (unquoted_name, block,
+                                       VAR_NAMESPACE, &symbols, &blocks);
+  if (n_matches == 0 && line_num >= 0)
+    error ("No line number information found for %s.", unquoted_name);
+  else if (n_matches == 0)
+    {
+#ifdef HPPA_COMPILER_BUG
+      /* FIXME: See comment in symtab.c::decode_line_1 */
+#undef volatile
+      volatile struct symtab_and_line val;
+#define volatile               /*nothing */
+#else
+      struct symtab_and_line val;
+#endif
+      struct minimal_symbol *msymbol;
+
+      INIT_SAL (&val);
+
+      msymbol = NULL;
+      if (lower_name != NULL)
+       msymbol = ada_lookup_minimal_symbol (ada_mangle (lower_name));
+      if (msymbol == NULL)
+       msymbol = ada_lookup_minimal_symbol (unquoted_name);
+      if (msymbol != NULL)
+       {
+         val.pc = SYMBOL_VALUE_ADDRESS (msymbol);
+         val.section = SYMBOL_BFD_SECTION (msymbol);
+         if (funfirstline)
+           {
+             val.pc += FUNCTION_START_OFFSET;
+             SKIP_PROLOGUE (val.pc);
+           }
+         selected.sals = (struct symtab_and_line *)
+           xmalloc (sizeof (struct symtab_and_line));
+         selected.sals[0] = val;
+         selected.nelts = 1;
+         return selected;
+       }
+
+      if (!have_full_symbols () &&
+         !have_partial_symbols () && !have_minimal_symbols ())
+       error (no_symtab_msg);
+
+      error ("Function \"%s\" not defined.", unquoted_name);
+      return selected;         /* for lint */
+    }
+
+  if (line_num >= 0)
+    {
+      return
+       find_sal_from_funcs_and_line (file_table->filename, line_num,
+                                     symbols, n_matches);
+    }
+  else
+    {
+      selected.nelts =
+       user_select_syms (symbols, blocks, n_matches, n_matches);
+    }
+
+  selected.sals = (struct symtab_and_line *)
+    xmalloc (sizeof (struct symtab_and_line) * selected.nelts);
+  memset (selected.sals, 0, selected.nelts * sizeof (selected.sals[i]));
+  make_cleanup (xfree, selected.sals);
+
+  i = 0;
+  while (i < selected.nelts)
+    {
+      if (SYMBOL_CLASS (symbols[i]) == LOC_BLOCK)
+       selected.sals[i] = find_function_start_sal (symbols[i], funfirstline);
+      else if (SYMBOL_LINE (symbols[i]) != 0)
+       {
+         selected.sals[i].symtab = symtab_for_sym (symbols[i]);
+         selected.sals[i].line = SYMBOL_LINE (symbols[i]);
+       }
+      else if (line_num >= 0)
+       {
+         /* Ignore this choice */
+         symbols[i] = symbols[selected.nelts - 1];
+         blocks[i] = blocks[selected.nelts - 1];
+         selected.nelts -= 1;
+         continue;
+       }
+      else
+       error ("Line number not known for symbol \"%s\"", unquoted_name);
+      i += 1;
+    }
+
+  if (canonical != NULL && (line_num >= 0 || n_matches > 1))
+    {
+      *canonical = (char **) xmalloc (sizeof (char *) * selected.nelts);
+      for (i = 0; i < selected.nelts; i += 1)
+       (*canonical)[i] =
+         extended_canonical_line_spec (selected.sals[i],
+                                       SYMBOL_SOURCE_NAME (symbols[i]));
+    }
+
+  discard_cleanups (old_chain);
+  return selected;
+}
+
+/* The (single) sal corresponding to line LINE_NUM in a symbol table
+   with file name FILENAME that occurs in one of the functions listed 
+   in SYMBOLS[0 .. NSYMS-1]. */
+static struct symtabs_and_lines
+find_sal_from_funcs_and_line (const char *filename, int line_num,
+                             struct symbol **symbols, int nsyms)
+{
+  struct symtabs_and_lines sals;
+  int best_index, best;
+  struct linetable *best_linetable;
+  struct objfile *objfile;
+  struct symtab *s;
+  struct symtab *best_symtab;
+
+  read_all_symtabs (filename);
+
+  best_index = 0;
+  best_linetable = NULL;
+  best_symtab = NULL;
+  best = 0;
+  ALL_SYMTABS (objfile, s)
+  {
+    struct linetable *l;
+    int ind, exact;
+
+    QUIT;
+
+    if (!STREQ (filename, s->filename))
+      continue;
+    l = LINETABLE (s);
+    ind = find_line_in_linetable (l, line_num, symbols, nsyms, &exact);
+    if (ind >= 0)
+      {
+       if (exact)
+         {
+           best_index = ind;
+           best_linetable = l;
+           best_symtab = s;
+           goto done;
+         }
+       if (best == 0 || l->item[ind].line < best)
+         {
+           best = l->item[ind].line;
+           best_index = ind;
+           best_linetable = l;
+           best_symtab = s;
+         }
+      }
+  }
+
+  if (best == 0)
+    error ("Line number not found in designated function.");
+
+done:
+
+  sals.nelts = 1;
+  sals.sals = (struct symtab_and_line *) xmalloc (sizeof (sals.sals[0]));
+
+  INIT_SAL (&sals.sals[0]);
+
+  sals.sals[0].line = best_linetable->item[best_index].line;
+  sals.sals[0].pc = best_linetable->item[best_index].pc;
+  sals.sals[0].symtab = best_symtab;
+
+  return sals;
+}
+
+/* Return the index in LINETABLE of the best match for LINE_NUM whose
+   pc falls within one of the functions denoted by SYMBOLS[0..NSYMS-1].  
+   Set *EXACTP to the 1 if the match is exact, and 0 otherwise. */
+static int
+find_line_in_linetable (struct linetable *linetable, int line_num,
+                       struct symbol **symbols, int nsyms, int *exactp)
+{
+  int i, len, best_index, best;
+
+  if (line_num <= 0 || linetable == NULL)
+    return -1;
+
+  len = linetable->nitems;
+  for (i = 0, best_index = -1, best = 0; i < len; i += 1)
+    {
+      int k;
+      struct linetable_entry *item = &(linetable->item[i]);
+
+      for (k = 0; k < nsyms; k += 1)
+       {
+         if (symbols[k] != NULL && SYMBOL_CLASS (symbols[k]) == LOC_BLOCK
+             && item->pc >= BLOCK_START (SYMBOL_BLOCK_VALUE (symbols[k]))
+             && item->pc < BLOCK_END (SYMBOL_BLOCK_VALUE (symbols[k])))
+           goto candidate;
+       }
+      continue;
+
+    candidate:
+
+      if (item->line == line_num)
+       {
+         *exactp = 1;
+         return i;
+       }
+
+      if (item->line > line_num && (best == 0 || item->line < best))
+       {
+         best = item->line;
+         best_index = i;
+       }
+    }
+
+  *exactp = 0;
+  return best_index;
+}
+
+/* Find the smallest k >= LINE_NUM such that k is a line number in
+   LINETABLE, and k falls strictly within a named function that begins at
+   or before LINE_NUM.  Return -1 if there is no such k. */
+static int
+nearest_line_number_in_linetable (struct linetable *linetable, int line_num)
+{
+  int i, len, best;
+
+  if (line_num <= 0 || linetable == NULL || linetable->nitems == 0)
+    return -1;
+  len = linetable->nitems;
+
+  i = 0;
+  best = INT_MAX;
+  while (i < len)
+    {
+      int k;
+      struct linetable_entry *item = &(linetable->item[i]);
+
+      if (item->line >= line_num && item->line < best)
+       {
+         char *func_name;
+         CORE_ADDR start, end;
+
+         func_name = NULL;
+         find_pc_partial_function (item->pc, &func_name, &start, &end);
+
+         if (func_name != NULL && item->pc < end)
+           {
+             if (item->line == line_num)
+               return line_num;
+             else
+               {
+                 struct symbol *sym =
+                   standard_lookup (func_name, VAR_NAMESPACE);
+                 if (is_plausible_func_for_line (sym, line_num))
+                   best = item->line;
+                 else
+                   {
+                     do
+                       i += 1;
+                     while (i < len && linetable->item[i].pc < end);
+                     continue;
+                   }
+               }
+           }
+       }
+
+      i += 1;
+    }
+
+  return (best == INT_MAX) ? -1 : best;
+}
+
+
+/* Return the next higher index, k, into LINETABLE such that k > IND, 
+   entry k in LINETABLE has a line number equal to LINE_NUM, k
+   corresponds to a PC that is in a function different from that 
+   corresponding to IND, and falls strictly within a named function
+   that begins at a line at or preceding STARTING_LINE.  
+   Return -1 if there is no such k.  
+   IND == -1 corresponds to no function. */
+
+static int
+find_next_line_in_linetable (struct linetable *linetable, int line_num,
+                            int starting_line, int ind)
+{
+  int i, len;
+
+  if (line_num <= 0 || linetable == NULL || ind >= linetable->nitems)
+    return -1;
+  len = linetable->nitems;
+
+  if (ind >= 0)
+    {
+      CORE_ADDR start, end;
+
+      if (find_pc_partial_function (linetable->item[ind].pc,
+                                   (char **) NULL, &start, &end))
+       {
+         while (ind < len && linetable->item[ind].pc < end)
+           ind += 1;
+       }
+      else
+       ind += 1;
+    }
+  else
+    ind = 0;
+
+  i = ind;
+  while (i < len)
+    {
+      int k;
+      struct linetable_entry *item = &(linetable->item[i]);
+
+      if (item->line >= line_num)
+       {
+         char *func_name;
+         CORE_ADDR start, end;
+
+         func_name = NULL;
+         find_pc_partial_function (item->pc, &func_name, &start, &end);
+
+         if (func_name != NULL && item->pc < end)
+           {
+             if (item->line == line_num)
+               {
+                 struct symbol *sym =
+                   standard_lookup (func_name, VAR_NAMESPACE);
+                 if (is_plausible_func_for_line (sym, starting_line))
+                   return i;
+                 else
+                   {
+                     while ((i + 1) < len && linetable->item[i + 1].pc < end)
+                       i += 1;
+                   }
+               }
+           }
+       }
+      i += 1;
+    }
+
+  return -1;
+}
+
+/* True iff function symbol SYM starts somewhere at or before line #
+   LINE_NUM. */
+static int
+is_plausible_func_for_line (struct symbol *sym, int line_num)
+{
+  struct symtab_and_line start_sal;
+
+  if (sym == NULL)
+    return 0;
+
+  start_sal = find_function_start_sal (sym, 0);
+
+  return (start_sal.line != 0 && line_num >= start_sal.line);
+}
+
+static void
+debug_print_lines (struct linetable *lt)
+{
+  int i;
+
+  if (lt == NULL)
+    return;
+
+  fprintf (stderr, "\t");
+  for (i = 0; i < lt->nitems; i += 1)
+    fprintf (stderr, "(%d->%p) ", lt->item[i].line, (void *) lt->item[i].pc);
+  fprintf (stderr, "\n");
+}
+
+static void
+debug_print_block (struct block *b)
+{
+  int i;
+  struct symbol *i;
+
+  fprintf (stderr, "Block: %p; [0x%lx, 0x%lx]",
+          b, BLOCK_START (b), BLOCK_END (b));
+  if (BLOCK_FUNCTION (b) != NULL)
+    fprintf (stderr, " Function: %s", SYMBOL_NAME (BLOCK_FUNCTION (b)));
+  fprintf (stderr, "\n");
+  fprintf (stderr, "\t    Superblock: %p\n", BLOCK_SUPERBLOCK (b));
+  fprintf (stderr, "\t    Symbols:");
+  ALL_BLOCK_SYMBOLS (b, i, sym)
+  {
+    if (i > 0 && i % 4 == 0)
+      fprintf (stderr, "\n\t\t    ");
+    fprintf (stderr, " %s", SYMBOL_NAME (sym));
+  }
+  fprintf (stderr, "\n");
+}
+
+static void
+debug_print_blocks (struct blockvector *bv)
+{
+  int i;
+
+  if (bv == NULL)
+    return;
+  for (i = 0; i < BLOCKVECTOR_NBLOCKS (bv); i += 1)
+    {
+      fprintf (stderr, "%6d. ", i);
+      debug_print_block (BLOCKVECTOR_BLOCK (bv, i));
+    }
+}
+
+static void
+debug_print_symtab (struct symtab *s)
+{
+  fprintf (stderr, "Symtab %p\n    File: %s; Dir: %s\n", s,
+          s->filename, s->dirname);
+  fprintf (stderr, "    Blockvector: %p, Primary: %d\n",
+          BLOCKVECTOR (s), s->primary);
+  debug_print_blocks (BLOCKVECTOR (s));
+  fprintf (stderr, "    Line table: %p\n", LINETABLE (s));
+  debug_print_lines (LINETABLE (s));
+}
+
+/* Read in all symbol tables corresponding to partial symbol tables
+   with file name FILENAME. */
+static void
+read_all_symtabs (const char *filename)
+{
+  struct partial_symtab *ps;
+  struct objfile *objfile;
+
+  ALL_PSYMTABS (objfile, ps)
+  {
+    QUIT;
+
+    if (STREQ (filename, ps->filename))
+      PSYMTAB_TO_SYMTAB (ps);
+  }
+}
+
+/* All sals corresponding to line LINE_NUM in a symbol table from file
+   FILENAME, as filtered by the user.  If CANONICAL is not null, set
+   it to a corresponding array of canonical line specs. */
+static struct symtabs_and_lines
+all_sals_for_line (const char *filename, int line_num, char ***canonical)
+{
+  struct symtabs_and_lines result;
+  struct objfile *objfile;
+  struct symtab *s;
+  struct cleanup *old_chain = make_cleanup (null_cleanup, NULL);
+  size_t len;
+
+  read_all_symtabs (filename);
+
+  result.sals =
+    (struct symtab_and_line *) xmalloc (4 * sizeof (result.sals[0]));
+  result.nelts = 0;
+  len = 4;
+  make_cleanup (free_current_contents, &result.sals);
+
+  ALL_SYMTABS (objfile, s)
+  {
+    int ind, target_line_num;
+
+    QUIT;
+
+    if (!STREQ (s->filename, filename))
+      continue;
+
+    target_line_num =
+      nearest_line_number_in_linetable (LINETABLE (s), line_num);
+    if (target_line_num == -1)
+      continue;
+
+    ind = -1;
+    while (1)
+      {
+       ind =
+         find_next_line_in_linetable (LINETABLE (s),
+                                      target_line_num, line_num, ind);
+
+       if (ind < 0)
+         break;
+
+       GROW_VECT (result.sals, len, result.nelts + 1);
+       INIT_SAL (&result.sals[result.nelts]);
+       result.sals[result.nelts].line = LINETABLE (s)->item[ind].line;
+       result.sals[result.nelts].pc = LINETABLE (s)->item[ind].pc;
+       result.sals[result.nelts].symtab = s;
+       result.nelts += 1;
+      }
+  }
+
+  if (canonical != NULL || result.nelts > 1)
+    {
+      int k;
+      char **func_names = (char **) alloca (result.nelts * sizeof (char *));
+      int first_choice = (result.nelts > 1) ? 2 : 1;
+      int n;
+      int *choices = (int *) alloca (result.nelts * sizeof (int));
+
+      for (k = 0; k < result.nelts; k += 1)
+       {
+         find_pc_partial_function (result.sals[k].pc, &func_names[k],
+                                   (CORE_ADDR *) NULL, (CORE_ADDR *) NULL);
+         if (func_names[k] == NULL)
+           error ("Could not find function for one or more breakpoints.");
+       }
+
+      if (result.nelts > 1)
+       {
+         printf_unfiltered ("[0] cancel\n");
+         if (result.nelts > 1)
+           printf_unfiltered ("[1] all\n");
+         for (k = 0; k < result.nelts; k += 1)
+           printf_unfiltered ("[%d] %s\n", k + first_choice,
+                              ada_demangle (func_names[k]));
+
+         n = get_selections (choices, result.nelts, result.nelts,
+                             result.nelts > 1, "instance-choice");
+
+         for (k = 0; k < n; k += 1)
+           {
+             result.sals[k] = result.sals[choices[k]];
+             func_names[k] = func_names[choices[k]];
+           }
+         result.nelts = n;
+       }
+
+      if (canonical != NULL)
+       {
+         *canonical = (char **) xmalloc (result.nelts * sizeof (char **));
+         make_cleanup (xfree, *canonical);
+         for (k = 0; k < result.nelts; k += 1)
+           {
+             (*canonical)[k] =
+               extended_canonical_line_spec (result.sals[k], func_names[k]);
+             if ((*canonical)[k] == NULL)
+               error ("Could not locate one or more breakpoints.");
+             make_cleanup (xfree, (*canonical)[k]);
+           }
+       }
+    }
+
+  discard_cleanups (old_chain);
+  return result;
+}
+
+
+/* A canonical line specification of the form FILE:NAME:LINENUM for
+   symbol table and line data SAL.  NULL if insufficient
+   information. The caller is responsible for releasing any space
+   allocated. */
+
+static char *
+extended_canonical_line_spec (struct symtab_and_line sal, const char *name)
+{
+  char *r;
+
+  if (sal.symtab == NULL || sal.symtab->filename == NULL || sal.line <= 0)
+    return NULL;
+
+  r = (char *) xmalloc (strlen (name) + strlen (sal.symtab->filename)
+                       + sizeof (sal.line) * 3 + 3);
+  sprintf (r, "%s:'%s':%d", sal.symtab->filename, name, sal.line);
+  return r;
+}
+
+#if 0
+int begin_bnum = -1;
+#endif
+int begin_annotate_level = 0;
+
+static void
+begin_cleanup (void *dummy)
+{
+  begin_annotate_level = 0;
+}
+
+static void
+begin_command (char *args, int from_tty)
+{
+  struct minimal_symbol *msym;
+  CORE_ADDR main_program_name_addr;
+  char main_program_name[1024];
+  struct cleanup *old_chain = make_cleanup (begin_cleanup, NULL);
+  begin_annotate_level = 2;
+
+  /* Check that there is a program to debug */
+  if (!have_full_symbols () && !have_partial_symbols ())
+    error ("No symbol table is loaded.  Use the \"file\" command.");
+
+  /* Check that we are debugging an Ada program */
+  /*  if (ada_update_initial_language (language_unknown, NULL) != language_ada)
+     error ("Cannot find the Ada initialization procedure.  Is this an Ada main program?");
+   */
+  /* FIXME: language_ada should be defined in defs.h */
+
+  /* Get the address of the name of the main procedure */
+  msym = lookup_minimal_symbol (ADA_MAIN_PROGRAM_SYMBOL_NAME, NULL, NULL);
+
+  if (msym != NULL)
+    {
+      main_program_name_addr = SYMBOL_VALUE_ADDRESS (msym);
+      if (main_program_name_addr == 0)
+       error ("Invalid address for Ada main program name.");
+
+      /* Read the name of the main procedure */
+      extract_string (main_program_name_addr, main_program_name);
+
+      /* Put a temporary breakpoint in the Ada main program and run */
+      do_command ("tbreak ", main_program_name, 0);
+      do_command ("run ", args, 0);
+    }
+  else
+    {
+      /* If we could not find the symbol containing the name of the
+         main program, that means that the compiler that was used to build
+         was not recent enough. In that case, we fallback to the previous
+         mechanism, which is a little bit less reliable, but has proved to work
+         in most cases. The only cases where it will fail is when the user
+         has set some breakpoints which will be hit before the end of the
+         begin command processing (eg in the initialization code).
+
+         The begining of the main Ada subprogram is located by breaking
+         on the adainit procedure. Since we know that the binder generates
+         the call to this procedure exactly 2 calls before the call to the
+         Ada main subprogram, it is then easy to put a breakpoint on this
+         Ada main subprogram once we hit adainit.
+       */
+      do_command ("tbreak adainit", 0);
+      do_command ("run ", args, 0);
+      do_command ("up", 0);
+      do_command ("tbreak +2", 0);
+      do_command ("continue", 0);
+      do_command ("step", 0);
+    }
+
+  do_cleanups (old_chain);
+}
+
+int
+is_ada_runtime_file (char *filename)
+{
+  return (STREQN (filename, "s-", 2) ||
+         STREQN (filename, "a-", 2) ||
+         STREQN (filename, "g-", 2) || STREQN (filename, "i-", 2));
+}
+
+/* find the first frame that contains debugging information and that is not
+   part of the Ada run-time, starting from fi and moving upward. */
+
+int
+find_printable_frame (struct frame_info *fi, int level)
+{
+  struct symtab_and_line sal;
+
+  for (; fi != NULL; level += 1, fi = get_prev_frame (fi))
+    {
+      /* If fi is not the innermost frame, that normally means that fi->pc
+         points to *after* the call instruction, and we want to get the line
+         containing the call, never the next line.  But if the next frame is
+         a signal_handler_caller or a dummy frame, then the next frame was
+         not entered as the result of a call, and we want to get the line
+         containing fi->pc.  */
+      sal =
+       find_pc_line (fi->pc,
+                     fi->next != NULL
+                     && !fi->next->signal_handler_caller
+                     && !frame_in_dummy (fi->next));
+      if (sal.symtab && !is_ada_runtime_file (sal.symtab->filename))
+       {
+#if defined(__alpha__) && defined(__osf__) && !defined(VXWORKS_TARGET)
+         /* libpthread.so contains some debugging information that prevents us
+            from finding the right frame */
+
+         if (sal.symtab->objfile &&
+             STREQ (sal.symtab->objfile->name, "/usr/shlib/libpthread.so"))
+           continue;
+#endif
+         selected_frame = fi;
+         break;
+       }
+    }
+
+  return level;
+}
+
+void
+ada_report_exception_break (struct breakpoint *b)
+{
+#ifdef UI_OUT
+  /* FIXME: break_on_exception should be defined in breakpoint.h */
+  /*  if (b->break_on_exception == 1)
+     {
+     /* Assume that cond has 16 elements, the 15th
+   being the exception *//*
+   if (b->cond && b->cond->nelts == 16)
+   {
+   ui_out_text (uiout, "on ");
+   ui_out_field_string (uiout, "exception",
+   SYMBOL_NAME (b->cond->elts[14].symbol));
+   }
+   else
+   ui_out_text (uiout, "on all exceptions");
+   }
+   else if (b->break_on_exception == 2)
+   ui_out_text (uiout, "on unhandled exception");
+   else if (b->break_on_exception == 3)
+   ui_out_text (uiout, "on assert failure");
+   #else
+   if (b->break_on_exception == 1)
+   { */
+  /* Assume that cond has 16 elements, the 15th
+   being the exception *//*
+   if (b->cond && b->cond->nelts == 16)
+   {
+   fputs_filtered ("on ", gdb_stdout);
+   fputs_filtered (SYMBOL_NAME
+   (b->cond->elts[14].symbol), gdb_stdout);
+   }
+   else
+   fputs_filtered ("on all exceptions", gdb_stdout);
+   }
+   else if (b->break_on_exception == 2)
+   fputs_filtered ("on unhandled exception", gdb_stdout);
+   else if (b->break_on_exception == 3)
+   fputs_filtered ("on assert failure", gdb_stdout);
+ */
+#endif
+}
+
+int
+ada_is_exception_sym (struct symbol *sym)
+{
+  char *type_name = type_name_no_tag (SYMBOL_TYPE (sym));
+
+  return (SYMBOL_CLASS (sym) != LOC_TYPEDEF
+         && SYMBOL_CLASS (sym) != LOC_BLOCK
+         && SYMBOL_CLASS (sym) != LOC_CONST
+         && type_name != NULL && STREQ (type_name, "exception"));
+}
+
+int
+ada_maybe_exception_partial_symbol (struct partial_symbol *sym)
+{
+  return (SYMBOL_CLASS (sym) != LOC_TYPEDEF
+         && SYMBOL_CLASS (sym) != LOC_BLOCK
+         && SYMBOL_CLASS (sym) != LOC_CONST);
+}
+
+/* If ARG points to an Ada exception or assert breakpoint, rewrite
+   into equivalent form.  Return resulting argument string. Set
+   *BREAK_ON_EXCEPTIONP to 1 for ordinary break on exception, 2 for
+   break on unhandled, 3 for assert, 0 otherwise. */
+char *
+ada_breakpoint_rewrite (char *arg, int *break_on_exceptionp)
+{
+  if (arg == NULL)
+    return arg;
+  *break_on_exceptionp = 0;
+  /* FIXME: language_ada should be defined in defs.h */
+  /*  if (current_language->la_language == language_ada
+     && STREQN (arg, "exception", 9) &&
+     (arg[9] == ' ' || arg[9] == '\t' || arg[9] == '\0'))
+     {
+     char *tok, *end_tok;
+     int toklen;
+
+     *break_on_exceptionp = 1;
+
+     tok = arg+9;
+     while (*tok == ' ' || *tok == '\t')
+     tok += 1;
+
+     end_tok = tok;
+
+     while (*end_tok != ' ' && *end_tok != '\t' && *end_tok != '\000')
+     end_tok += 1;
+
+     toklen = end_tok - tok;
+
+     arg = (char*) xmalloc (sizeof ("__gnat_raise_nodefer_with_msg if "
+     "long_integer(e) = long_integer(&)")
+     + toklen + 1);
+     make_cleanup (xfree, arg);
+     if (toklen == 0)
+     strcpy (arg, "__gnat_raise_nodefer_with_msg");
+     else if (STREQN (tok, "unhandled", toklen))
+     {
+     *break_on_exceptionp = 2;
+     strcpy (arg, "__gnat_unhandled_exception");
+     }
+     else
+     {
+     sprintf (arg, "__gnat_raise_nodefer_with_msg if "
+     "long_integer(e) = long_integer(&%.*s)", 
+     toklen, tok);
+     }
+     }
+     else if (current_language->la_language == language_ada
+     && STREQN (arg, "assert", 6) &&
+     (arg[6] == ' ' || arg[6] == '\t' || arg[6] == '\0'))
+     {
+     char *tok = arg + 6;
+
+     *break_on_exceptionp = 3;
+
+     arg = (char*) 
+     xmalloc (sizeof ("system__assertions__raise_assert_failure")
+     + strlen (tok) + 1);
+     make_cleanup (xfree, arg);
+     sprintf (arg, "system__assertions__raise_assert_failure%s", tok);
+     }
+   */
+  return arg;
+}
+\f
+
+                               /* Field Access */
+
+/* True if field number FIELD_NUM in struct or union type TYPE is supposed
+   to be invisible to users. */
+
+int
+ada_is_ignored_field (struct type *type, int field_num)
+{
+  if (field_num < 0 || field_num > TYPE_NFIELDS (type))
+    return 1;
+  else
+    {
+      const char *name = TYPE_FIELD_NAME (type, field_num);
+      return (name == NULL
+             || (name[0] == '_' && !STREQN (name, "_parent", 7)));
+    }
+}
+
+/* True iff structure type TYPE has a tag field. */
+
+int
+ada_is_tagged_type (struct type *type)
+{
+  if (type == NULL || TYPE_CODE (type) != TYPE_CODE_STRUCT)
+    return 0;
+
+  return (ada_lookup_struct_elt_type (type, "_tag", 1, NULL) != NULL);
+}
+
+/* The type of the tag on VAL. */
+
+struct type *
+ada_tag_type (struct value *val)
+{
+  return ada_lookup_struct_elt_type (VALUE_TYPE (val), "_tag", 0, NULL);
+}
+
+/* The value of the tag on VAL. */
+
+struct value *
+ada_value_tag (struct value *val)
+{
+  return ada_value_struct_elt (val, "_tag", "record");
+}
+
+/* The parent type of TYPE, or NULL if none. */
+
+struct type *
+ada_parent_type (struct type *type)
+{
+  int i;
+
+  CHECK_TYPEDEF (type);
+
+  if (type == NULL || TYPE_CODE (type) != TYPE_CODE_STRUCT)
+    return NULL;
+
+  for (i = 0; i < TYPE_NFIELDS (type); i += 1)
+    if (ada_is_parent_field (type, i))
+      return check_typedef (TYPE_FIELD_TYPE (type, i));
+
+  return NULL;
+}
+
+/* True iff field number FIELD_NUM of structure type TYPE contains the 
+   parent-type (inherited) fields of a derived type.  Assumes TYPE is 
+   a structure type with at least FIELD_NUM+1 fields. */
+
+int
+ada_is_parent_field (struct type *type, int field_num)
+{
+  const char *name = TYPE_FIELD_NAME (check_typedef (type), field_num);
+  return (name != NULL &&
+         (STREQN (name, "PARENT", 6) || STREQN (name, "_parent", 7)));
+}
+
+/* True iff field number FIELD_NUM of structure type TYPE is a 
+   transparent wrapper field (which should be silently traversed when doing
+   field selection and flattened when printing).  Assumes TYPE is a 
+   structure type with at least FIELD_NUM+1 fields.  Such fields are always
+   structures. */
+
+int
+ada_is_wrapper_field (struct type *type, int field_num)
+{
+  const char *name = TYPE_FIELD_NAME (type, field_num);
+  return (name != NULL
+         && (STREQN (name, "PARENT", 6) || STREQ (name, "REP")
+             || STREQN (name, "_parent", 7)
+             || name[0] == 'S' || name[0] == 'R' || name[0] == 'O'));
+}
+
+/* True iff field number FIELD_NUM of structure or union type TYPE 
+   is a variant wrapper.  Assumes TYPE is a structure type with at least 
+   FIELD_NUM+1 fields. */
+
+int
+ada_is_variant_part (struct type *type, int field_num)
+{
+  struct type *field_type = TYPE_FIELD_TYPE (type, field_num);
+  return (TYPE_CODE (field_type) == TYPE_CODE_UNION
+         || (is_dynamic_field (type, field_num)
+             && TYPE_CODE (TYPE_TARGET_TYPE (field_type)) ==
+             TYPE_CODE_UNION));
+}
+
+/* Assuming that VAR_TYPE is a variant wrapper (type of the variant part)
+   whose discriminants are contained in the record type OUTER_TYPE, 
+   returns the type of the controlling discriminant for the variant.  */
+
+struct type *
+ada_variant_discrim_type (struct type *var_type, struct type *outer_type)
+{
+  char *name = ada_variant_discrim_name (var_type);
+  struct type *type = ada_lookup_struct_elt_type (outer_type, name, 1, NULL);
+  if (type == NULL)
+    return builtin_type_int;
+  else
+    return type;
+}
+
+/* Assuming that TYPE is the type of a variant wrapper, and FIELD_NUM is a 
+   valid field number within it, returns 1 iff field FIELD_NUM of TYPE
+   represents a 'when others' clause; otherwise 0. */
+
+int
+ada_is_others_clause (struct type *type, int field_num)
+{
+  const char *name = TYPE_FIELD_NAME (type, field_num);
+  return (name != NULL && name[0] == 'O');
+}
+
+/* Assuming that TYPE0 is the type of the variant part of a record,
+   returns the name of the discriminant controlling the variant.  The
+   value is valid until the next call to ada_variant_discrim_name. */
+
+char *
+ada_variant_discrim_name (struct type *type0)
+{
+  static char *result = NULL;
+  static size_t result_len = 0;
+  struct type *type;
+  const char *name;
+  const char *discrim_end;
+  const char *discrim_start;
+
+  if (TYPE_CODE (type0) == TYPE_CODE_PTR)
+    type = TYPE_TARGET_TYPE (type0);
+  else
+    type = type0;
+
+  name = ada_type_name (type);
+
+  if (name == NULL || name[0] == '\000')
+    return "";
+
+  for (discrim_end = name + strlen (name) - 6; discrim_end != name;
+       discrim_end -= 1)
+    {
+      if (STREQN (discrim_end, "___XVN", 6))
+       break;
+    }
+  if (discrim_end == name)
+    return "";
+
+  for (discrim_start = discrim_end; discrim_start != name + 3;
+       discrim_start -= 1)
+    {
+      if (discrim_start == name + 1)
+       return "";
+      if ((discrim_start > name + 3 && STREQN (discrim_start - 3, "___", 3))
+         || discrim_start[-1] == '.')
+       break;
+    }
+
+  GROW_VECT (result, result_len, discrim_end - discrim_start + 1);
+  strncpy (result, discrim_start, discrim_end - discrim_start);
+  result[discrim_end - discrim_start] = '\0';
+  return result;
+}
+
+/* Scan STR for a subtype-encoded number, beginning at position K. Put the 
+   position of the character just past the number scanned in *NEW_K, 
+   if NEW_K!=NULL. Put the scanned number in *R, if R!=NULL.  Return 1 
+   if there was a valid number at the given position, and 0 otherwise.  A 
+   "subtype-encoded" number consists of the absolute value in decimal, 
+   followed by the letter 'm' to indicate a negative number.  Assumes 0m 
+   does not occur. */
+
+int
+ada_scan_number (const char str[], int k, LONGEST * R, int *new_k)
+{
+  ULONGEST RU;
+
+  if (!isdigit (str[k]))
+    return 0;
+
+  /* Do it the hard way so as not to make any assumption about 
+     the relationship of unsigned long (%lu scan format code) and
+     LONGEST. */
+  RU = 0;
+  while (isdigit (str[k]))
+    {
+      RU = RU * 10 + (str[k] - '0');
+      k += 1;
+    }
+
+  if (str[k] == 'm')
+    {
+      if (R != NULL)
+       *R = (-(LONGEST) (RU - 1)) - 1;
+      k += 1;
+    }
+  else if (R != NULL)
+    *R = (LONGEST) RU;
+
+  /* NOTE on the above: Technically, C does not say what the results of 
+     - (LONGEST) RU or (LONGEST) -RU are for RU == largest positive
+     number representable as a LONGEST (although either would probably work
+     in most implementations).  When RU>0, the locution in the then branch
+     above is always equivalent to the negative of RU. */
+
+  if (new_k != NULL)
+    *new_k = k;
+  return 1;
+}
+
+/* Assuming that TYPE is a variant part wrapper type (a VARIANTS field), 
+   and FIELD_NUM is a valid field number within it, returns 1 iff VAL is 
+   in the range encoded by field FIELD_NUM of TYPE; otherwise 0. */
+
+int
+ada_in_variant (LONGEST val, struct type *type, int field_num)
+{
+  const char *name = TYPE_FIELD_NAME (type, field_num);
+  int p;
+
+  p = 0;
+  while (1)
+    {
+      switch (name[p])
+       {
+       case '\0':
+         return 0;
+       case 'S':
+         {
+           LONGEST W;
+           if (!ada_scan_number (name, p + 1, &W, &p))
+             return 0;
+           if (val == W)
+             return 1;
+           break;
+         }
+       case 'R':
+         {
+           LONGEST L, U;
+           if (!ada_scan_number (name, p + 1, &L, &p)
+               || name[p] != 'T' || !ada_scan_number (name, p + 1, &U, &p))
+             return 0;
+           if (val >= L && val <= U)
+             return 1;
+           break;
+         }
+       case 'O':
+         return 1;
+       default:
+         return 0;
+       }
+    }
+}
+
+/* Given a value ARG1 (offset by OFFSET bytes)
+   of a struct or union type ARG_TYPE,
+   extract and return the value of one of its (non-static) fields.
+   FIELDNO says which field.   Differs from value_primitive_field only
+   in that it can handle packed values of arbitrary type. */
+
+struct value *
+ada_value_primitive_field (struct value *arg1, int offset, int fieldno,
+                          struct type *arg_type)
+{
+  struct value *v;
+  struct type *type;
+
+  CHECK_TYPEDEF (arg_type);
+  type = TYPE_FIELD_TYPE (arg_type, fieldno);
+
+  /* Handle packed fields */
+
+  if (TYPE_FIELD_BITSIZE (arg_type, fieldno) != 0)
+    {
+      int bit_pos = TYPE_FIELD_BITPOS (arg_type, fieldno);
+      int bit_size = TYPE_FIELD_BITSIZE (arg_type, fieldno);
+
+      return ada_value_primitive_packed_val (arg1, VALUE_CONTENTS (arg1),
+                                            offset + bit_pos / 8,
+                                            bit_pos % 8, bit_size, type);
+    }
+  else
+    return value_primitive_field (arg1, offset, fieldno, arg_type);
+}
+
+
+/* Look for a field NAME in ARG. Adjust the address of ARG by OFFSET bytes,
+   and search in it assuming it has (class) type TYPE.
+   If found, return value, else return NULL.
+
+   Searches recursively through wrapper fields (e.g., '_parent'). */
+
+struct value *
+ada_search_struct_field (char *name, struct value *arg, int offset,
+                        struct type *type)
+{
+  int i;
+  CHECK_TYPEDEF (type);
+
+  for (i = TYPE_NFIELDS (type) - 1; i >= 0; i -= 1)
+    {
+      char *t_field_name = TYPE_FIELD_NAME (type, i);
+
+      if (t_field_name == NULL)
+       continue;
+
+      else if (field_name_match (t_field_name, name))
+       return ada_value_primitive_field (arg, offset, i, type);
+
+      else if (ada_is_wrapper_field (type, i))
+       {
+         struct value *v = ada_search_struct_field (name, arg,
+                                                    offset +
+                                                    TYPE_FIELD_BITPOS (type,
+                                                                       i) /
+                                                    8,
+                                                    TYPE_FIELD_TYPE (type,
+                                                                     i));
+         if (v != NULL)
+           return v;
+       }
+
+      else if (ada_is_variant_part (type, i))
+       {
+         int j;
+         struct type *field_type = check_typedef (TYPE_FIELD_TYPE (type, i));
+         int var_offset = offset + TYPE_FIELD_BITPOS (type, i) / 8;
+
+         for (j = TYPE_NFIELDS (field_type) - 1; j >= 0; j -= 1)
+           {
+             struct value *v = ada_search_struct_field (name, arg,
+                                                        var_offset
+                                                        +
+                                                        TYPE_FIELD_BITPOS
+                                                        (field_type, j) / 8,
+                                                        TYPE_FIELD_TYPE
+                                                        (field_type, j));
+             if (v != NULL)
+               return v;
+           }
+       }
+    }
+  return NULL;
+}
+
+/* Given ARG, a value of type (pointer to a)* structure/union,
+   extract the component named NAME from the ultimate target structure/union
+   and return it as a value with its appropriate type.
+
+   The routine searches for NAME among all members of the structure itself 
+   and (recursively) among all members of any wrapper members 
+   (e.g., '_parent').
+
+   ERR is a name (for use in error messages) that identifies the class 
+   of entity that ARG is supposed to be. */
+
+struct value *
+ada_value_struct_elt (struct value *arg, char *name, char *err)
+{
+  struct type *t;
+  struct value *v;
+
+  arg = ada_coerce_ref (arg);
+  t = check_typedef (VALUE_TYPE (arg));
+
+  /* Follow pointers until we get to a non-pointer.  */
+
+  while (TYPE_CODE (t) == TYPE_CODE_PTR || TYPE_CODE (t) == TYPE_CODE_REF)
+    {
+      arg = ada_value_ind (arg);
+      t = check_typedef (VALUE_TYPE (arg));
+    }
+
+  if (TYPE_CODE (t) != TYPE_CODE_STRUCT && TYPE_CODE (t) != TYPE_CODE_UNION)
+    error ("Attempt to extract a component of a value that is not a %s.",
+          err);
+
+  v = ada_search_struct_field (name, arg, 0, t);
+  if (v == NULL)
+    error ("There is no member named %s.", name);
+
+  return v;
+}
+
+/* Given a type TYPE, look up the type of the component of type named NAME.
+   If DISPP is non-null, add its byte displacement from the beginning of a 
+   structure (pointed to by a value) of type TYPE to *DISPP (does not 
+   work for packed fields).
+
+   Matches any field whose name has NAME as a prefix, possibly
+   followed by "___". 
+
+   TYPE can be either a struct or union, or a pointer or reference to 
+   a struct or union.  If it is a pointer or reference, its target 
+   type is automatically used.
+
+   Looks recursively into variant clauses and parent types.
+
+   If NOERR is nonzero, return NULL if NAME is not suitably defined. */
+
+struct type *
+ada_lookup_struct_elt_type (struct type *type, char *name, int noerr,
+                           int *dispp)
+{
+  int i;
+
+  if (name == NULL)
+    goto BadName;
+
+  while (1)
+    {
+      CHECK_TYPEDEF (type);
+      if (TYPE_CODE (type) != TYPE_CODE_PTR
+         && TYPE_CODE (type) != TYPE_CODE_REF)
+       break;
+      type = TYPE_TARGET_TYPE (type);
+    }
+
+  if (TYPE_CODE (type) != TYPE_CODE_STRUCT &&
+      TYPE_CODE (type) != TYPE_CODE_UNION)
+    {
+      target_terminal_ours ();
+      gdb_flush (gdb_stdout);
+      fprintf_unfiltered (gdb_stderr, "Type ");
+      type_print (type, "", gdb_stderr, -1);
+      error (" is not a structure or union type");
+    }
+
+  type = to_static_fixed_type (type);
+
+  for (i = 0; i < TYPE_NFIELDS (type); i += 1)
+    {
+      char *t_field_name = TYPE_FIELD_NAME (type, i);
+      struct type *t;
+      int disp;
+
+      if (t_field_name == NULL)
+       continue;
+
+      else if (field_name_match (t_field_name, name))
+       {
+         if (dispp != NULL)
+           *dispp += TYPE_FIELD_BITPOS (type, i) / 8;
+         return check_typedef (TYPE_FIELD_TYPE (type, i));
+       }
+
+      else if (ada_is_wrapper_field (type, i))
+       {
+         disp = 0;
+         t = ada_lookup_struct_elt_type (TYPE_FIELD_TYPE (type, i), name,
+                                         1, &disp);
+         if (t != NULL)
+           {
+             if (dispp != NULL)
+               *dispp += disp + TYPE_FIELD_BITPOS (type, i) / 8;
+             return t;
+           }
+       }
+
+      else if (ada_is_variant_part (type, i))
+       {
+         int j;
+         struct type *field_type = check_typedef (TYPE_FIELD_TYPE (type, i));
+
+         for (j = TYPE_NFIELDS (field_type) - 1; j >= 0; j -= 1)
+           {
+             disp = 0;
+             t = ada_lookup_struct_elt_type (TYPE_FIELD_TYPE (field_type, j),
+                                             name, 1, &disp);
+             if (t != NULL)
+               {
+                 if (dispp != NULL)
+                   *dispp += disp + TYPE_FIELD_BITPOS (type, i) / 8;
+                 return t;
+               }
+           }
+       }
+
+    }
+
+BadName:
+  if (!noerr)
+    {
+      target_terminal_ours ();
+      gdb_flush (gdb_stdout);
+      fprintf_unfiltered (gdb_stderr, "Type ");
+      type_print (type, "", gdb_stderr, -1);
+      fprintf_unfiltered (gdb_stderr, " has no component named ");
+      error ("%s", name == NULL ? "<null>" : name);
+    }
+
+  return NULL;
+}
+
+/* Assuming that VAR_TYPE is the type of a variant part of a record (a union),
+   within a value of type OUTER_TYPE that is stored in GDB at
+   OUTER_VALADDR, determine which variant clause (field number in VAR_TYPE, 
+   numbering from 0) is applicable.  Returns -1 if none are. */
+
+int
+ada_which_variant_applies (struct type *var_type, struct type *outer_type,
+                          char *outer_valaddr)
+{
+  int others_clause;
+  int i;
+  int disp;
+  struct type *discrim_type;
+  char *discrim_name = ada_variant_discrim_name (var_type);
+  LONGEST discrim_val;
+
+  disp = 0;
+  discrim_type =
+    ada_lookup_struct_elt_type (outer_type, discrim_name, 1, &disp);
+  if (discrim_type == NULL)
+    return -1;
+  discrim_val = unpack_long (discrim_type, outer_valaddr + disp);
+
+  others_clause = -1;
+  for (i = 0; i < TYPE_NFIELDS (var_type); i += 1)
+    {
+      if (ada_is_others_clause (var_type, i))
+       others_clause = i;
+      else if (ada_in_variant (discrim_val, var_type, i))
+       return i;
+    }
+
+  return others_clause;
+}
+\f
+
+
+                               /* Dynamic-Sized Records */
+
+/* Strategy: The type ostensibly attached to a value with dynamic size
+   (i.e., a size that is not statically recorded in the debugging
+   data) does not accurately reflect the size or layout of the value.
+   Our strategy is to convert these values to values with accurate,
+   conventional types that are constructed on the fly. */
+
+/* There is a subtle and tricky problem here.  In general, we cannot
+   determine the size of dynamic records without its data.  However,
+   the 'struct value' data structure, which GDB uses to represent
+   quantities in the inferior process (the target), requires the size
+   of the type at the time of its allocation in order to reserve space
+   for GDB's internal copy of the data.  That's why the
+   'to_fixed_xxx_type' routines take (target) addresses as parameters,
+   rather than struct value*s.  
+
+   However, GDB's internal history variables ($1, $2, etc.) are
+   struct value*s containing internal copies of the data that are not, in
+   general, the same as the data at their corresponding addresses in
+   the target.  Fortunately, the types we give to these values are all
+   conventional, fixed-size types (as per the strategy described
+   above), so that we don't usually have to perform the
+   'to_fixed_xxx_type' conversions to look at their values.
+   Unfortunately, there is one exception: if one of the internal
+   history variables is an array whose elements are unconstrained
+   records, then we will need to create distinct fixed types for each
+   element selected.  */
+
+/* The upshot of all of this is that many routines take a (type, host
+   address, target address) triple as arguments to represent a value.
+   The host address, if non-null, is supposed to contain an internal
+   copy of the relevant data; otherwise, the program is to consult the
+   target at the target address. */
+
+/* Assuming that VAL0 represents a pointer value, the result of
+   dereferencing it.  Differs from value_ind in its treatment of
+   dynamic-sized types. */
+
+struct value *
+ada_value_ind (struct value *val0)
+{
+  struct value *val = unwrap_value (value_ind (val0));
+  return ada_to_fixed_value (VALUE_TYPE (val), 0,
+                            VALUE_ADDRESS (val) + VALUE_OFFSET (val), val);
+}
+
+/* The value resulting from dereferencing any "reference to"
+ * qualifiers on VAL0. */
+static struct value *
+ada_coerce_ref (struct value *val0)
+{
+  if (TYPE_CODE (VALUE_TYPE (val0)) == TYPE_CODE_REF)
+    {
+      struct value *val = val0;
+      COERCE_REF (val);
+      val = unwrap_value (val);
+      return ada_to_fixed_value (VALUE_TYPE (val), 0,
+                                VALUE_ADDRESS (val) + VALUE_OFFSET (val),
+                                val);
+    }
+  else
+    return val0;
+}
+
+/* Return OFF rounded upward if necessary to a multiple of
+   ALIGNMENT (a power of 2). */
+
+static unsigned int
+align_value (unsigned int off, unsigned int alignment)
+{
+  return (off + alignment - 1) & ~(alignment - 1);
+}
+
+/* Return the additional bit offset required by field F of template
+   type TYPE. */
+
+static unsigned int
+field_offset (struct type *type, int f)
+{
+  int n = TYPE_FIELD_BITPOS (type, f);
+  /* Kludge (temporary?) to fix problem with dwarf output. */
+  if (n < 0)
+    return (unsigned int) n & 0xffff;
+  else
+    return n;
+}
+
+
+/* Return the bit alignment required for field #F of template type TYPE. */
+
+static unsigned int
+field_alignment (struct type *type, int f)
+{
+  const char *name = TYPE_FIELD_NAME (type, f);
+  int len = (name == NULL) ? 0 : strlen (name);
+  int align_offset;
+
+  if (len < 8 || !isdigit (name[len - 1]))
+    return TARGET_CHAR_BIT;
+
+  if (isdigit (name[len - 2]))
+    align_offset = len - 2;
+  else
+    align_offset = len - 1;
+
+  if (align_offset < 7 || !STREQN ("___XV", name + align_offset - 6, 5))
+    return TARGET_CHAR_BIT;
+
+  return atoi (name + align_offset) * TARGET_CHAR_BIT;
+}
+
+/* Find a type named NAME.  Ignores ambiguity.  */
+struct type *
+ada_find_any_type (const char *name)
+{
+  struct symbol *sym;
+
+  sym = standard_lookup (name, VAR_NAMESPACE);
+  if (sym != NULL && SYMBOL_CLASS (sym) == LOC_TYPEDEF)
+    return SYMBOL_TYPE (sym);
+
+  sym = standard_lookup (name, STRUCT_NAMESPACE);
+  if (sym != NULL)
+    return SYMBOL_TYPE (sym);
+
+  return NULL;
+}
+
+/* Because of GNAT encoding conventions, several GDB symbols may match a
+   given type name. If the type denoted by TYPE0 is to be preferred to
+   that of TYPE1 for purposes of type printing, return non-zero;
+   otherwise return 0. */
+int
+ada_prefer_type (struct type *type0, struct type *type1)
+{
+  if (type1 == NULL)
+    return 1;
+  else if (type0 == NULL)
+    return 0;
+  else if (TYPE_CODE (type1) == TYPE_CODE_VOID)
+    return 1;
+  else if (TYPE_CODE (type0) == TYPE_CODE_VOID)
+    return 0;
+  else if (ada_is_packed_array_type (type0))
+    return 1;
+  else if (ada_is_array_descriptor (type0)
+          && !ada_is_array_descriptor (type1))
+    return 1;
+  else if (ada_renaming_type (type0) != NULL
+          && ada_renaming_type (type1) == NULL)
+    return 1;
+  return 0;
+}
+
+/* The name of TYPE, which is either its TYPE_NAME, or, if that is
+   null, its TYPE_TAG_NAME.  Null if TYPE is null. */
+char *
+ada_type_name (struct type *type)
+{
+  if (type == NULL)
+    return NULL;
+  else if (TYPE_NAME (type) != NULL)
+    return TYPE_NAME (type);
+  else
+    return TYPE_TAG_NAME (type);
+}
+
+/* Find a parallel type to TYPE whose name is formed by appending
+   SUFFIX to the name of TYPE. */
+
+struct type *
+ada_find_parallel_type (struct type *type, const char *suffix)
+{
+  static char *name;
+  static size_t name_len = 0;
+  struct symbol **syms;
+  struct block **blocks;
+  int nsyms;
+  int len;
+  char *typename = ada_type_name (type);
+
+  if (typename == NULL)
+    return NULL;
+
+  len = strlen (typename);
+
+  GROW_VECT (name, name_len, len + strlen (suffix) + 1);
+
+  strcpy (name, typename);
+  strcpy (name + len, suffix);
+
+  return ada_find_any_type (name);
+}
+
+
+/* If TYPE is a variable-size record type, return the corresponding template
+   type describing its fields.  Otherwise, return NULL. */
+
+static struct type *
+dynamic_template_type (struct type *type)
+{
+  CHECK_TYPEDEF (type);
+
+  if (type == NULL || TYPE_CODE (type) != TYPE_CODE_STRUCT
+      || ada_type_name (type) == NULL)
+    return NULL;
+  else
+    {
+      int len = strlen (ada_type_name (type));
+      if (len > 6 && STREQ (ada_type_name (type) + len - 6, "___XVE"))
+       return type;
+      else
+       return ada_find_parallel_type (type, "___XVE");
+    }
+}
+
+/* Assuming that TEMPL_TYPE is a union or struct type, returns
+   non-zero iff field FIELD_NUM of TEMPL_TYPE has dynamic size. */
+
+static int
+is_dynamic_field (struct type *templ_type, int field_num)
+{
+  const char *name = TYPE_FIELD_NAME (templ_type, field_num);
+  return name != NULL
+    && TYPE_CODE (TYPE_FIELD_TYPE (templ_type, field_num)) == TYPE_CODE_PTR
+    && strstr (name, "___XVL") != NULL;
+}
+
+/* Assuming that TYPE is a struct type, returns non-zero iff TYPE
+   contains a variant part. */
+
+static int
+contains_variant_part (struct type *type)
+{
+  int f;
+
+  if (type == NULL || TYPE_CODE (type) != TYPE_CODE_STRUCT
+      || TYPE_NFIELDS (type) <= 0)
+    return 0;
+  return ada_is_variant_part (type, TYPE_NFIELDS (type) - 1);
+}
+
+/* A record type with no fields, . */
+static struct type *
+empty_record (struct objfile *objfile)
+{
+  struct type *type = alloc_type (objfile);
+  TYPE_CODE (type) = TYPE_CODE_STRUCT;
+  TYPE_NFIELDS (type) = 0;
+  TYPE_FIELDS (type) = NULL;
+  TYPE_NAME (type) = "<empty>";
+  TYPE_TAG_NAME (type) = NULL;
+  TYPE_FLAGS (type) = 0;
+  TYPE_LENGTH (type) = 0;
+  return type;
+}
+
+/* An ordinary record type (with fixed-length fields) that describes
+   the value of type TYPE at VALADDR or ADDRESS (see comments at 
+   the beginning of this section) VAL according to GNAT conventions.  
+   DVAL0 should describe the (portion of a) record that contains any 
+   necessary discriminants.  It should be NULL if VALUE_TYPE (VAL) is
+   an outer-level type (i.e., as opposed to a branch of a variant.)  A
+   variant field (unless unchecked) is replaced by a particular branch
+   of the variant. */
+/* NOTE: Limitations: For now, we assume that dynamic fields and
+ * variants occupy whole numbers of bytes.  However, they need not be
+ * byte-aligned.  */
+
+static struct type *
+template_to_fixed_record_type (struct type *type, char *valaddr,
+                              CORE_ADDR address, struct value *dval0)
+{
+  struct value *mark = value_mark ();
+  struct value *dval;
+  struct type *rtype;
+  int nfields, bit_len;
+  long off;
+  int f;
+
+  nfields = TYPE_NFIELDS (type);
+  rtype = alloc_type (TYPE_OBJFILE (type));
+  TYPE_CODE (rtype) = TYPE_CODE_STRUCT;
+  INIT_CPLUS_SPECIFIC (rtype);
+  TYPE_NFIELDS (rtype) = nfields;
+  TYPE_FIELDS (rtype) = (struct field *)
+    TYPE_ALLOC (rtype, nfields * sizeof (struct field));
+  memset (TYPE_FIELDS (rtype), 0, sizeof (struct field) * nfields);
+  TYPE_NAME (rtype) = ada_type_name (type);
+  TYPE_TAG_NAME (rtype) = NULL;
+  /* FIXME: TYPE_FLAG_FIXED_INSTANCE should be defined in
+     gdbtypes.h */
+  /*  TYPE_FLAGS (rtype) |= TYPE_FLAG_FIXED_INSTANCE; */
+
+  off = 0;
+  bit_len = 0;
+  for (f = 0; f < nfields; f += 1)
+    {
+      int fld_bit_len, bit_incr;
+      off =
+       align_value (off,
+                    field_alignment (type, f)) + TYPE_FIELD_BITPOS (type, f);
+      /* NOTE: used to use field_offset above, but that causes
+       * problems with really negative bit positions.  So, let's
+       * rediscover why we needed field_offset and fix it properly. */
+      TYPE_FIELD_BITPOS (rtype, f) = off;
+      TYPE_FIELD_BITSIZE (rtype, f) = 0;
+
+      if (ada_is_variant_part (type, f))
+       {
+         struct type *branch_type;
+
+         if (dval0 == NULL)
+           dval = value_from_contents_and_address (rtype, valaddr, address);
+         else
+           dval = dval0;
+
+         branch_type =
+           to_fixed_variant_branch_type
+           (TYPE_FIELD_TYPE (type, f),
+            cond_offset_host (valaddr, off / TARGET_CHAR_BIT),
+            cond_offset_target (address, off / TARGET_CHAR_BIT), dval);
+         if (branch_type == NULL)
+           TYPE_NFIELDS (rtype) -= 1;
+         else
+           {
+             TYPE_FIELD_TYPE (rtype, f) = branch_type;
+             TYPE_FIELD_NAME (rtype, f) = "S";
+           }
+         bit_incr = 0;
+         fld_bit_len =
+           TYPE_LENGTH (TYPE_FIELD_TYPE (rtype, f)) * TARGET_CHAR_BIT;
+       }
+      else if (is_dynamic_field (type, f))
+       {
+         if (dval0 == NULL)
+           dval = value_from_contents_and_address (rtype, valaddr, address);
+         else
+           dval = dval0;
+
+         TYPE_FIELD_TYPE (rtype, f) =
+           ada_to_fixed_type
+           (ada_get_base_type
+            (TYPE_TARGET_TYPE (TYPE_FIELD_TYPE (type, f))),
+            cond_offset_host (valaddr, off / TARGET_CHAR_BIT),
+            cond_offset_target (address, off / TARGET_CHAR_BIT), dval);
+         TYPE_FIELD_NAME (rtype, f) = TYPE_FIELD_NAME (type, f);
+         bit_incr = fld_bit_len =
+           TYPE_LENGTH (TYPE_FIELD_TYPE (rtype, f)) * TARGET_CHAR_BIT;
+       }
+      else
+       {
+         TYPE_FIELD_TYPE (rtype, f) = TYPE_FIELD_TYPE (type, f);
+         TYPE_FIELD_NAME (rtype, f) = TYPE_FIELD_NAME (type, f);
+         if (TYPE_FIELD_BITSIZE (type, f) > 0)
+           bit_incr = fld_bit_len =
+             TYPE_FIELD_BITSIZE (rtype, f) = TYPE_FIELD_BITSIZE (type, f);
+         else
+           bit_incr = fld_bit_len =
+             TYPE_LENGTH (TYPE_FIELD_TYPE (type, f)) * TARGET_CHAR_BIT;
+       }
+      if (off + fld_bit_len > bit_len)
+       bit_len = off + fld_bit_len;
+      off += bit_incr;
+      TYPE_LENGTH (rtype) = bit_len / TARGET_CHAR_BIT;
+    }
+  TYPE_LENGTH (rtype) = align_value (TYPE_LENGTH (rtype), TYPE_LENGTH (type));
+
+  value_free_to_mark (mark);
+  if (TYPE_LENGTH (rtype) > varsize_limit)
+    error ("record type with dynamic size is larger than varsize-limit");
+  return rtype;
+}
+
+/* As for template_to_fixed_record_type, but uses no run-time values.
+   As a result, this type can only be approximate, but that's OK,
+   since it is used only for type determinations.   Works on both
+   structs and unions.
+   Representation note: to save space, we memoize the result of this
+   function in the TYPE_TARGET_TYPE of the template type. */
+
+static struct type *
+template_to_static_fixed_type (struct type *templ_type)
+{
+  struct type *type;
+  int nfields;
+  int f;
+
+  if (TYPE_TARGET_TYPE (templ_type) != NULL)
+    return TYPE_TARGET_TYPE (templ_type);
+
+  nfields = TYPE_NFIELDS (templ_type);
+  TYPE_TARGET_TYPE (templ_type) = type =
+    alloc_type (TYPE_OBJFILE (templ_type));
+  TYPE_CODE (type) = TYPE_CODE (templ_type);
+  INIT_CPLUS_SPECIFIC (type);
+  TYPE_NFIELDS (type) = nfields;
+  TYPE_FIELDS (type) = (struct field *)
+    TYPE_ALLOC (type, nfields * sizeof (struct field));
+  memset (TYPE_FIELDS (type), 0, sizeof (struct field) * nfields);
+  TYPE_NAME (type) = ada_type_name (templ_type);
+  TYPE_TAG_NAME (type) = NULL;
+  /* FIXME:  TYPE_FLAG_FIXED_INSTANCE should be defined in gdbtypes.h */
+  /*  TYPE_FLAGS (type) |= TYPE_FLAG_FIXED_INSTANCE; */
+  TYPE_LENGTH (type) = 0;
+
+  for (f = 0; f < nfields; f += 1)
+    {
+      TYPE_FIELD_BITPOS (type, f) = 0;
+      TYPE_FIELD_BITSIZE (type, f) = 0;
+
+      if (is_dynamic_field (templ_type, f))
+       {
+         TYPE_FIELD_TYPE (type, f) =
+           to_static_fixed_type (TYPE_TARGET_TYPE
+                                 (TYPE_FIELD_TYPE (templ_type, f)));
+         TYPE_FIELD_NAME (type, f) = TYPE_FIELD_NAME (templ_type, f);
+       }
+      else
+       {
+         TYPE_FIELD_TYPE (type, f) =
+           check_typedef (TYPE_FIELD_TYPE (templ_type, f));
+         TYPE_FIELD_NAME (type, f) = TYPE_FIELD_NAME (templ_type, f);
+       }
+    }
+
+  return type;
+}
+
+/* A revision of TYPE0 -- a non-dynamic-sized record with a variant
+   part -- in which the variant part is replaced with the appropriate
+   branch. */
+static struct type *
+to_record_with_fixed_variant_part (struct type *type, char *valaddr,
+                                  CORE_ADDR address, struct value *dval)
+{
+  struct value *mark = value_mark ();
+  struct type *rtype;
+  struct type *branch_type;
+  int nfields = TYPE_NFIELDS (type);
+
+  if (dval == NULL)
+    return type;
+
+  rtype = alloc_type (TYPE_OBJFILE (type));
+  TYPE_CODE (rtype) = TYPE_CODE_STRUCT;
+  INIT_CPLUS_SPECIFIC (type);
+  TYPE_NFIELDS (rtype) = TYPE_NFIELDS (type);
+  TYPE_FIELDS (rtype) =
+    (struct field *) TYPE_ALLOC (rtype, nfields * sizeof (struct field));
+  memcpy (TYPE_FIELDS (rtype), TYPE_FIELDS (type),
+         sizeof (struct field) * nfields);
+  TYPE_NAME (rtype) = ada_type_name (type);
+  TYPE_TAG_NAME (rtype) = NULL;
+  /* FIXME:  TYPE_FLAG_FIXED_INSTANCE should be defined in gdbtypes.h */
+  /*  TYPE_FLAGS (rtype) |= TYPE_FLAG_FIXED_INSTANCE; */
+  TYPE_LENGTH (rtype) = TYPE_LENGTH (type);
+
+  branch_type =
+    to_fixed_variant_branch_type
+    (TYPE_FIELD_TYPE (type, nfields - 1),
+     cond_offset_host (valaddr,
+                      TYPE_FIELD_BITPOS (type,
+                                         nfields - 1) / TARGET_CHAR_BIT),
+     cond_offset_target (address,
+                        TYPE_FIELD_BITPOS (type,
+                                           nfields - 1) / TARGET_CHAR_BIT),
+     dval);
+  if (branch_type == NULL)
+    {
+      TYPE_NFIELDS (rtype) -= 1;
+      TYPE_LENGTH (rtype) -=
+       TYPE_LENGTH (TYPE_FIELD_TYPE (type, nfields - 1));
+    }
+  else
+    {
+      TYPE_FIELD_TYPE (rtype, nfields - 1) = branch_type;
+      TYPE_FIELD_NAME (rtype, nfields - 1) = "S";
+      TYPE_FIELD_BITSIZE (rtype, nfields - 1) = 0;
+      TYPE_LENGTH (rtype) += TYPE_LENGTH (branch_type);
+      -TYPE_LENGTH (TYPE_FIELD_TYPE (type, nfields - 1));
+    }
+
+  return rtype;
+}
+
+/* An ordinary record type (with fixed-length fields) that describes
+   the value at (TYPE0, VALADDR, ADDRESS) [see explanation at
+   beginning of this section].   Any necessary discriminants' values
+   should be in DVAL, a record value; it should be NULL if the object
+   at ADDR itself contains any necessary  discriminant values.  A
+   variant field (unless unchecked) is replaced by a particular branch
+   of the variant. */
+
+static struct type *
+to_fixed_record_type (struct type *type0, char *valaddr, CORE_ADDR address,
+                     struct value *dval)
+{
+  struct type *templ_type;
+
+  /* FIXME:  TYPE_FLAG_FIXED_INSTANCE should be defined in gdbtypes.h */
+  /*  if (TYPE_FLAGS (type0) & TYPE_FLAG_FIXED_INSTANCE)
+     return type0;
+   */
+  templ_type = dynamic_template_type (type0);
+
+  if (templ_type != NULL)
+    return template_to_fixed_record_type (templ_type, valaddr, address, dval);
+  else if (contains_variant_part (type0))
+    return to_record_with_fixed_variant_part (type0, valaddr, address, dval);
+  else
+    {
+      /* FIXME:  TYPE_FLAG_FIXED_INSTANCE should be defined in gdbtypes.h */
+      /*      TYPE_FLAGS (type0) |= TYPE_FLAG_FIXED_INSTANCE; */
+      return type0;
+    }
+
+}
+
+/* An ordinary record type (with fixed-length fields) that describes
+   the value at (VAR_TYPE0, VALADDR, ADDRESS), where VAR_TYPE0 is a
+   union type.  Any necessary discriminants' values should be in DVAL,
+   a record value.  That is, this routine selects the appropriate
+   branch of the union at ADDR according to the discriminant value
+   indicated in the union's type name. */
+
+static struct type *
+to_fixed_variant_branch_type (struct type *var_type0, char *valaddr,
+                             CORE_ADDR address, struct value *dval)
+{
+  int which;
+  struct type *templ_type;
+  struct type *var_type;
+
+  if (TYPE_CODE (var_type0) == TYPE_CODE_PTR)
+    var_type = TYPE_TARGET_TYPE (var_type0);
+  else
+    var_type = var_type0;
+
+  templ_type = ada_find_parallel_type (var_type, "___XVU");
+
+  if (templ_type != NULL)
+    var_type = templ_type;
+
+  which =
+    ada_which_variant_applies (var_type,
+                              VALUE_TYPE (dval), VALUE_CONTENTS (dval));
+
+  if (which < 0)
+    return empty_record (TYPE_OBJFILE (var_type));
+  else if (is_dynamic_field (var_type, which))
+    return
+      to_fixed_record_type
+      (TYPE_TARGET_TYPE (TYPE_FIELD_TYPE (var_type, which)),
+       valaddr, address, dval);
+  else if (contains_variant_part (TYPE_FIELD_TYPE (var_type, which)))
+    return
+      to_fixed_record_type
+      (TYPE_FIELD_TYPE (var_type, which), valaddr, address, dval);
+  else
+    return TYPE_FIELD_TYPE (var_type, which);
+}
+
+/* Assuming that TYPE0 is an array type describing the type of a value
+   at ADDR, and that DVAL describes a record containing any
+   discriminants used in TYPE0, returns a type for the value that
+   contains no dynamic components (that is, no components whose sizes
+   are determined by run-time quantities).  Unless IGNORE_TOO_BIG is
+   true, gives an error message if the resulting type's size is over
+   varsize_limit.
+*/
+
+static struct type *
+to_fixed_array_type (struct type *type0, struct value *dval,
+                    int ignore_too_big)
+{
+  struct type *index_type_desc;
+  struct type *result;
+
+  /* FIXME:  TYPE_FLAG_FIXED_INSTANCE should be defined in gdbtypes.h */
+/*  if (ada_is_packed_array_type (type0)  /* revisit? *//*
+   || (TYPE_FLAGS (type0) & TYPE_FLAG_FIXED_INSTANCE))
+   return type0; */
+
+  index_type_desc = ada_find_parallel_type (type0, "___XA");
+  if (index_type_desc == NULL)
+    {
+      struct type *elt_type0 = check_typedef (TYPE_TARGET_TYPE (type0));
+      /* NOTE: elt_type---the fixed version of elt_type0---should never
+       * depend on the contents of the array in properly constructed
+       * debugging data. */
+      struct type *elt_type = ada_to_fixed_type (elt_type0, 0, 0, dval);
+
+      if (elt_type0 == elt_type)
+       result = type0;
+      else
+       result = create_array_type (alloc_type (TYPE_OBJFILE (type0)),
+                                   elt_type, TYPE_INDEX_TYPE (type0));
+    }
+  else
+    {
+      int i;
+      struct type *elt_type0;
+
+      elt_type0 = type0;
+      for (i = TYPE_NFIELDS (index_type_desc); i > 0; i -= 1)
+       elt_type0 = TYPE_TARGET_TYPE (elt_type0);
+
+      /* NOTE: result---the fixed version of elt_type0---should never
+       * depend on the contents of the array in properly constructed
+       * debugging data. */
+      result = ada_to_fixed_type (check_typedef (elt_type0), 0, 0, dval);
+      for (i = TYPE_NFIELDS (index_type_desc) - 1; i >= 0; i -= 1)
+       {
+         struct type *range_type =
+           to_fixed_range_type (TYPE_FIELD_NAME (index_type_desc, i),
+                                dval, TYPE_OBJFILE (type0));
+         result = create_array_type (alloc_type (TYPE_OBJFILE (type0)),
+                                     result, range_type);
+       }
+      if (!ignore_too_big && TYPE_LENGTH (result) > varsize_limit)
+       error ("array type with dynamic size is larger than varsize-limit");
+    }
+
+/* FIXME:  TYPE_FLAG_FIXED_INSTANCE should be defined in gdbtypes.h */
+/*  TYPE_FLAGS (result) |= TYPE_FLAG_FIXED_INSTANCE; */
+  return result;
+}
+
+
+/* A standard type (containing no dynamically sized components)
+   corresponding to TYPE for the value (TYPE, VALADDR, ADDRESS)
+   DVAL describes a record containing any discriminants used in TYPE0,
+   and may be NULL if there are none. */
+
+struct type *
+ada_to_fixed_type (struct type *type, char *valaddr, CORE_ADDR address,
+                  struct value *dval)
+{
+  CHECK_TYPEDEF (type);
+  switch (TYPE_CODE (type))
+    {
+    default:
+      return type;
+    case TYPE_CODE_STRUCT:
+      return to_fixed_record_type (type, valaddr, address, NULL);
+    case TYPE_CODE_ARRAY:
+      return to_fixed_array_type (type, dval, 0);
+    case TYPE_CODE_UNION:
+      if (dval == NULL)
+       return type;
+      else
+       return to_fixed_variant_branch_type (type, valaddr, address, dval);
+    }
+}
+
+/* A standard (static-sized) type corresponding as well as possible to
+   TYPE0, but based on no runtime data. */
+
+static struct type *
+to_static_fixed_type (struct type *type0)
+{
+  struct type *type;
+
+  if (type0 == NULL)
+    return NULL;
+
+  /* FIXME:  TYPE_FLAG_FIXED_INSTANCE should be defined in gdbtypes.h */
+  /*  if (TYPE_FLAGS (type0) & TYPE_FLAG_FIXED_INSTANCE)
+     return type0;
+   */
+  CHECK_TYPEDEF (type0);
+
+  switch (TYPE_CODE (type0))
+    {
+    default:
+      return type0;
+    case TYPE_CODE_STRUCT:
+      type = dynamic_template_type (type0);
+      if (type != NULL)
+       return template_to_static_fixed_type (type);
+      return type0;
+    case TYPE_CODE_UNION:
+      type = ada_find_parallel_type (type0, "___XVU");
+      if (type != NULL)
+       return template_to_static_fixed_type (type);
+      return type0;
+    }
+}
+
+/* A static approximation of TYPE with all type wrappers removed. */
+static struct type *
+static_unwrap_type (struct type *type)
+{
+  if (ada_is_aligner_type (type))
+    {
+      struct type *type1 = TYPE_FIELD_TYPE (check_typedef (type), 0);
+      if (ada_type_name (type1) == NULL)
+       TYPE_NAME (type1) = ada_type_name (type);
+
+      return static_unwrap_type (type1);
+    }
+  else
+    {
+      struct type *raw_real_type = ada_get_base_type (type);
+      if (raw_real_type == type)
+       return type;
+      else
+       return to_static_fixed_type (raw_real_type);
+    }
+}
+
+/* In some cases, incomplete and private types require
+   cross-references that are not resolved as records (for example, 
+      type Foo;
+      type FooP is access Foo;
+      V: FooP;
+      type Foo is array ...;
+   ). In these cases, since there is no mechanism for producing 
+   cross-references to such types, we instead substitute for FooP a
+   stub enumeration type that is nowhere resolved, and whose tag is
+   the name of the actual type.  Call these types "non-record stubs". */
+
+/* A type equivalent to TYPE that is not a non-record stub, if one
+   exists, otherwise TYPE. */
+struct type *
+ada_completed_type (struct type *type)
+{
+  CHECK_TYPEDEF (type);
+  if (type == NULL || TYPE_CODE (type) != TYPE_CODE_ENUM
+      || (TYPE_FLAGS (type) & TYPE_FLAG_STUB) == 0
+      || TYPE_TAG_NAME (type) == NULL)
+    return type;
+  else
+    {
+      char *name = TYPE_TAG_NAME (type);
+      struct type *type1 = ada_find_any_type (name);
+      return (type1 == NULL) ? type : type1;
+    }
+}
+
+/* A value representing the data at VALADDR/ADDRESS as described by
+   type TYPE0, but with a standard (static-sized) type that correctly
+   describes it.  If VAL0 is not NULL and TYPE0 already is a standard
+   type, then return VAL0 [this feature is simply to avoid redundant
+   creation of struct values]. */
+
+struct value *
+ada_to_fixed_value (struct type *type0, char *valaddr, CORE_ADDR address,
+                   struct value *val0)
+{
+  struct type *type = ada_to_fixed_type (type0, valaddr, address, NULL);
+  if (type == type0 && val0 != NULL)
+    return val0;
+  else
+    return value_from_contents_and_address (type, valaddr, address);
+}
+
+/* A value representing VAL, but with a standard (static-sized) type 
+   chosen to approximate the real type of VAL as well as possible, but
+   without consulting any runtime values.  For Ada dynamic-sized
+   types, therefore, the type of the result is likely to be inaccurate. */
+
+struct value *
+ada_to_static_fixed_value (struct value *val)
+{
+  struct type *type =
+    to_static_fixed_type (static_unwrap_type (VALUE_TYPE (val)));
+  if (type == VALUE_TYPE (val))
+    return val;
+  else
+    return coerce_unspec_val_to_type (val, 0, type);
+}
+\f
+
+
+
+
+/* Attributes */
+
+/* Table mapping attribute numbers to names */
+/* NOTE: Keep up to date with enum ada_attribute definition in ada-lang.h */
+
+static const char *attribute_names[] = {
+  "<?>",
+
+  "first",
+  "last",
+  "length",
+  "image",
+  "img",
+  "max",
+  "min",
+  "pos" "tag",
+  "val",
+
+  0
+};
+
+const char *
+ada_attribute_name (int n)
+{
+  if (n > 0 && n < (int) ATR_END)
+    return attribute_names[n];
+  else
+    return attribute_names[0];
+}
+
+/* Evaluate the 'POS attribute applied to ARG. */
+
+static struct value *
+value_pos_atr (struct value *arg)
+{
+  struct type *type = VALUE_TYPE (arg);
+
+  if (!discrete_type_p (type))
+    error ("'POS only defined on discrete types");
+
+  if (TYPE_CODE (type) == TYPE_CODE_ENUM)
+    {
+      int i;
+      LONGEST v = value_as_long (arg);
+
+      for (i = 0; i < TYPE_NFIELDS (type); i += 1)
+       {
+         if (v == TYPE_FIELD_BITPOS (type, i))
+           return value_from_longest (builtin_type_ada_int, i);
+       }
+      error ("enumeration value is invalid: can't find 'POS");
+    }
+  else
+    return value_from_longest (builtin_type_ada_int, value_as_long (arg));
+}
+
+/* Evaluate the TYPE'VAL attribute applied to ARG. */
+
+static struct value *
+value_val_atr (struct type *type, struct value *arg)
+{
+  if (!discrete_type_p (type))
+    error ("'VAL only defined on discrete types");
+  if (!integer_type_p (VALUE_TYPE (arg)))
+    error ("'VAL requires integral argument");
+
+  if (TYPE_CODE (type) == TYPE_CODE_ENUM)
+    {
+      long pos = value_as_long (arg);
+      if (pos < 0 || pos >= TYPE_NFIELDS (type))
+       error ("argument to 'VAL out of range");
+      return value_from_longest (type, TYPE_FIELD_BITPOS (type, pos));
+    }
+  else
+    return value_from_longest (type, value_as_long (arg));
+}
+\f
+
+                               /* Evaluation */
+
+/* True if TYPE appears to be an Ada character type.  
+ * [At the moment, this is true only for Character and Wide_Character;
+ * It is a heuristic test that could stand improvement]. */
+
+int
+ada_is_character_type (struct type *type)
+{
+  const char *name = ada_type_name (type);
+  return
+    name != NULL
+    && (TYPE_CODE (type) == TYPE_CODE_CHAR
+       || TYPE_CODE (type) == TYPE_CODE_INT
+       || TYPE_CODE (type) == TYPE_CODE_RANGE)
+    && (STREQ (name, "character") || STREQ (name, "wide_character")
+       || STREQ (name, "unsigned char"));
+}
+
+/* True if TYPE appears to be an Ada string type. */
+
+int
+ada_is_string_type (struct type *type)
+{
+  CHECK_TYPEDEF (type);
+  if (type != NULL
+      && TYPE_CODE (type) != TYPE_CODE_PTR
+      && (ada_is_simple_array (type) || ada_is_array_descriptor (type))
+      && ada_array_arity (type) == 1)
+    {
+      struct type *elttype = ada_array_element_type (type, 1);
+
+      return ada_is_character_type (elttype);
+    }
+  else
+    return 0;
+}
+
+
+/* True if TYPE is a struct type introduced by the compiler to force the
+   alignment of a value.  Such types have a single field with a
+   distinctive name. */
+
+int
+ada_is_aligner_type (struct type *type)
+{
+  CHECK_TYPEDEF (type);
+  return (TYPE_CODE (type) == TYPE_CODE_STRUCT
+         && TYPE_NFIELDS (type) == 1
+         && STREQ (TYPE_FIELD_NAME (type, 0), "F"));
+}
+
+/* If there is an ___XVS-convention type parallel to SUBTYPE, return
+   the parallel type. */
+
+struct type *
+ada_get_base_type (struct type *raw_type)
+{
+  struct type *real_type_namer;
+  struct type *raw_real_type;
+  struct type *real_type;
+
+  if (raw_type == NULL || TYPE_CODE (raw_type) != TYPE_CODE_STRUCT)
+    return raw_type;
+
+  real_type_namer = ada_find_parallel_type (raw_type, "___XVS");
+  if (real_type_namer == NULL
+      || TYPE_CODE (real_type_namer) != TYPE_CODE_STRUCT
+      || TYPE_NFIELDS (real_type_namer) != 1)
+    return raw_type;
+
+  raw_real_type = ada_find_any_type (TYPE_FIELD_NAME (real_type_namer, 0));
+  if (raw_real_type == NULL)
+    return raw_type;
+  else
+    return raw_real_type;
+}
+
+/* The type of value designated by TYPE, with all aligners removed. */
+
+struct type *
+ada_aligned_type (struct type *type)
+{
+  if (ada_is_aligner_type (type))
+    return ada_aligned_type (TYPE_FIELD_TYPE (type, 0));
+  else
+    return ada_get_base_type (type);
+}
+
+
+/* The address of the aligned value in an object at address VALADDR
+   having type TYPE.  Assumes ada_is_aligner_type (TYPE). */
+
+char *
+ada_aligned_value_addr (struct type *type, char *valaddr)
+{
+  if (ada_is_aligner_type (type))
+    return ada_aligned_value_addr (TYPE_FIELD_TYPE (type, 0),
+                                  valaddr +
+                                  TYPE_FIELD_BITPOS (type,
+                                                     0) / TARGET_CHAR_BIT);
+  else
+    return valaddr;
+}
+
+/* The printed representation of an enumeration literal with encoded
+   name NAME. The value is good to the next call of ada_enum_name. */
+const char *
+ada_enum_name (const char *name)
+{
+  char *tmp;
+
+  while (1)
+    {
+      if ((tmp = strstr (name, "__")) != NULL)
+       name = tmp + 2;
+      else if ((tmp = strchr (name, '.')) != NULL)
+       name = tmp + 1;
+      else
+       break;
+    }
+
+  if (name[0] == 'Q')
+    {
+      static char result[16];
+      int v;
+      if (name[1] == 'U' || name[1] == 'W')
+       {
+         if (sscanf (name + 2, "%x", &v) != 1)
+           return name;
+       }
+      else
+       return name;
+
+      if (isascii (v) && isprint (v))
+       sprintf (result, "'%c'", v);
+      else if (name[1] == 'U')
+       sprintf (result, "[\"%02x\"]", v);
+      else
+       sprintf (result, "[\"%04x\"]", v);
+
+      return result;
+    }
+  else
+    return name;
+}
+
+static struct value *
+evaluate_subexp (struct type *expect_type, struct expression *exp, int *pos,
+                enum noside noside)
+{
+  return (*exp->language_defn->evaluate_exp) (expect_type, exp, pos, noside);
+}
+
+/* Evaluate the subexpression of EXP starting at *POS as for
+   evaluate_type, updating *POS to point just past the evaluated
+   expression. */
+
+static struct value *
+evaluate_subexp_type (struct expression *exp, int *pos)
+{
+  return (*exp->language_defn->evaluate_exp)
+    (NULL_TYPE, exp, pos, EVAL_AVOID_SIDE_EFFECTS);
+}
+
+/* If VAL is wrapped in an aligner or subtype wrapper, return the
+   value it wraps. */
+
+static struct value *
+unwrap_value (struct value *val)
+{
+  struct type *type = check_typedef (VALUE_TYPE (val));
+  if (ada_is_aligner_type (type))
+    {
+      struct value *v = value_struct_elt (&val, NULL, "F",
+                                         NULL, "internal structure");
+      struct type *val_type = check_typedef (VALUE_TYPE (v));
+      if (ada_type_name (val_type) == NULL)
+       TYPE_NAME (val_type) = ada_type_name (type);
+
+      return unwrap_value (v);
+    }
+  else
+    {
+      struct type *raw_real_type =
+       ada_completed_type (ada_get_base_type (type));
+
+      if (type == raw_real_type)
+       return val;
+
+      return
+       coerce_unspec_val_to_type
+       (val, 0, ada_to_fixed_type (raw_real_type, 0,
+                                   VALUE_ADDRESS (val) + VALUE_OFFSET (val),
+                                   NULL));
+    }
+}
+
+static struct value *
+cast_to_fixed (struct type *type, struct value *arg)
+{
+  LONGEST val;
+
+  if (type == VALUE_TYPE (arg))
+    return arg;
+  else if (ada_is_fixed_point_type (VALUE_TYPE (arg)))
+    val = ada_float_to_fixed (type,
+                             ada_fixed_to_float (VALUE_TYPE (arg),
+                                                 value_as_long (arg)));
+  else
+    {
+      DOUBLEST argd =
+       value_as_double (value_cast (builtin_type_double, value_copy (arg)));
+      val = ada_float_to_fixed (type, argd);
+    }
+
+  return value_from_longest (type, val);
+}
+
+static struct value *
+cast_from_fixed_to_double (struct value *arg)
+{
+  DOUBLEST val = ada_fixed_to_float (VALUE_TYPE (arg),
+                                    value_as_long (arg));
+  return value_from_double (builtin_type_double, val);
+}
+
+/* Coerce VAL as necessary for assignment to an lval of type TYPE, and 
+ * return the converted value. */
+static struct value *
+coerce_for_assign (struct type *type, struct value *val)
+{
+  struct type *type2 = VALUE_TYPE (val);
+  if (type == type2)
+    return val;
+
+  CHECK_TYPEDEF (type2);
+  CHECK_TYPEDEF (type);
+
+  if (TYPE_CODE (type2) == TYPE_CODE_PTR
+      && TYPE_CODE (type) == TYPE_CODE_ARRAY)
+    {
+      val = ada_value_ind (val);
+      type2 = VALUE_TYPE (val);
+    }
+
+  if (TYPE_CODE (type2) == TYPE_CODE_ARRAY
+      && TYPE_CODE (type) == TYPE_CODE_ARRAY)
+    {
+      if (TYPE_LENGTH (type2) != TYPE_LENGTH (type)
+         || TYPE_LENGTH (TYPE_TARGET_TYPE (type2))
+         != TYPE_LENGTH (TYPE_TARGET_TYPE (type2)))
+       error ("Incompatible types in assignment");
+      VALUE_TYPE (val) = type;
+    }
+  return val;
+}
+
+struct value *
+ada_evaluate_subexp (struct type *expect_type, struct expression *exp,
+                    int *pos, enum noside noside)
+{
+  enum exp_opcode op;
+  enum ada_attribute atr;
+  int tem, tem2, tem3;
+  int pc;
+  struct value *arg1 = NULL, *arg2 = NULL, *arg3;
+  struct type *type;
+  int nargs;
+  struct value **argvec;
+
+  pc = *pos;
+  *pos += 1;
+  op = exp->elts[pc].opcode;
+
+  switch (op)
+    {
+    default:
+      *pos -= 1;
+      return
+       unwrap_value (evaluate_subexp_standard
+                     (expect_type, exp, pos, noside));
+
+    case UNOP_CAST:
+      (*pos) += 2;
+      type = exp->elts[pc + 1].type;
+      arg1 = evaluate_subexp (type, exp, pos, noside);
+      if (noside == EVAL_SKIP)
+       goto nosideret;
+      if (type != check_typedef (VALUE_TYPE (arg1)))
+       {
+         if (ada_is_fixed_point_type (type))
+           arg1 = cast_to_fixed (type, arg1);
+         else if (ada_is_fixed_point_type (VALUE_TYPE (arg1)))
+           arg1 = value_cast (type, cast_from_fixed_to_double (arg1));
+         else if (VALUE_LVAL (arg1) == lval_memory)
+           {
+             /* This is in case of the really obscure (and undocumented,
+                but apparently expected) case of (Foo) Bar.all, where Bar 
+                is an integer constant and Foo is a dynamic-sized type.
+                If we don't do this, ARG1 will simply be relabeled with
+                TYPE. */
+             if (noside == EVAL_AVOID_SIDE_EFFECTS)
+               return value_zero (to_static_fixed_type (type), not_lval);
+             arg1 =
+               ada_to_fixed_value
+               (type, 0, VALUE_ADDRESS (arg1) + VALUE_OFFSET (arg1), 0);
+           }
+         else
+           arg1 = value_cast (type, arg1);
+       }
+      return arg1;
+
+      /* FIXME:  UNOP_QUAL should be defined in expression.h */
+      /*    case UNOP_QUAL:
+         (*pos) += 2;
+         type = exp->elts[pc + 1].type;
+         return ada_evaluate_subexp (type, exp, pos, noside);
+       */
+    case BINOP_ASSIGN:
+      arg1 = evaluate_subexp (NULL_TYPE, exp, pos, noside);
+      arg2 = evaluate_subexp (VALUE_TYPE (arg1), exp, pos, noside);
+      if (noside == EVAL_SKIP || noside == EVAL_AVOID_SIDE_EFFECTS)
+       return arg1;
+      if (binop_user_defined_p (op, arg1, arg2))
+       return value_x_binop (arg1, arg2, op, OP_NULL, EVAL_NORMAL);
+      else
+       {
+         if (ada_is_fixed_point_type (VALUE_TYPE (arg1)))
+           arg2 = cast_to_fixed (VALUE_TYPE (arg1), arg2);
+         else if (ada_is_fixed_point_type (VALUE_TYPE (arg2)))
+           error
+             ("Fixed-point values must be assigned to fixed-point variables");
+         else
+           arg2 = coerce_for_assign (VALUE_TYPE (arg1), arg2);
+         return ada_value_assign (arg1, arg2);
+       }
+
+    case BINOP_ADD:
+      arg1 = evaluate_subexp_with_coercion (exp, pos, noside);
+      arg2 = evaluate_subexp_with_coercion (exp, pos, noside);
+      if (noside == EVAL_SKIP)
+       goto nosideret;
+      if (binop_user_defined_p (op, arg1, arg2))
+       return value_x_binop (arg1, arg2, op, OP_NULL, EVAL_NORMAL);
+      else
+       {
+         if ((ada_is_fixed_point_type (VALUE_TYPE (arg1))
+              || ada_is_fixed_point_type (VALUE_TYPE (arg2)))
+             && VALUE_TYPE (arg1) != VALUE_TYPE (arg2))
+           error
+             ("Operands of fixed-point addition must have the same type");
+         return value_cast (VALUE_TYPE (arg1), value_add (arg1, arg2));
+       }
+
+    case BINOP_SUB:
+      arg1 = evaluate_subexp_with_coercion (exp, pos, noside);
+      arg2 = evaluate_subexp_with_coercion (exp, pos, noside);
+      if (noside == EVAL_SKIP)
+       goto nosideret;
+      if (binop_user_defined_p (op, arg1, arg2))
+       return value_x_binop (arg1, arg2, op, OP_NULL, EVAL_NORMAL);
+      else
+       {
+         if ((ada_is_fixed_point_type (VALUE_TYPE (arg1))
+              || ada_is_fixed_point_type (VALUE_TYPE (arg2)))
+             && VALUE_TYPE (arg1) != VALUE_TYPE (arg2))
+           error
+             ("Operands of fixed-point subtraction must have the same type");
+         return value_cast (VALUE_TYPE (arg1), value_sub (arg1, arg2));
+       }
+
+    case BINOP_MUL:
+    case BINOP_DIV:
+      arg1 = evaluate_subexp (NULL_TYPE, exp, pos, noside);
+      arg2 = evaluate_subexp (NULL_TYPE, exp, pos, noside);
+      if (noside == EVAL_SKIP)
+       goto nosideret;
+      if (binop_user_defined_p (op, arg1, arg2))
+       return value_x_binop (arg1, arg2, op, OP_NULL, EVAL_NORMAL);
+      else
+       if (noside == EVAL_AVOID_SIDE_EFFECTS
+           && (op == BINOP_DIV || op == BINOP_REM || op == BINOP_MOD))
+       return value_zero (VALUE_TYPE (arg1), not_lval);
+      else
+       {
+         if (ada_is_fixed_point_type (VALUE_TYPE (arg1)))
+           arg1 = cast_from_fixed_to_double (arg1);
+         if (ada_is_fixed_point_type (VALUE_TYPE (arg2)))
+           arg2 = cast_from_fixed_to_double (arg2);
+         return value_binop (arg1, arg2, op);
+       }
+
+    case UNOP_NEG:
+      arg1 = evaluate_subexp (NULL_TYPE, exp, pos, noside);
+      if (noside == EVAL_SKIP)
+       goto nosideret;
+      if (unop_user_defined_p (op, arg1))
+       return value_x_unop (arg1, op, EVAL_NORMAL);
+      else if (ada_is_fixed_point_type (VALUE_TYPE (arg1)))
+       return value_cast (VALUE_TYPE (arg1), value_neg (arg1));
+      else
+       return value_neg (arg1);
+
+      /* FIXME:  OP_UNRESOLVED_VALUE should be defined in expression.h */
+      /*    case OP_UNRESOLVED_VALUE:
+         /* Only encountered when an unresolved symbol occurs in a
+         context other than a function call, in which case, it is
+   illegal. *//*
+   (*pos) += 3;
+   if (noside == EVAL_SKIP)
+   goto nosideret;
+   else 
+   error ("Unexpected unresolved symbol, %s, during evaluation",
+   ada_demangle (exp->elts[pc + 2].name));
+ */
+    case OP_VAR_VALUE:
+      *pos -= 1;
+      if (noside == EVAL_SKIP)
+       {
+         *pos += 4;
+         goto nosideret;
+       }
+      else if (noside == EVAL_AVOID_SIDE_EFFECTS)
+       {
+         *pos += 4;
+         return value_zero
+           (to_static_fixed_type
+            (static_unwrap_type (SYMBOL_TYPE (exp->elts[pc + 2].symbol))),
+            not_lval);
+       }
+      else
+       {
+         arg1 =
+           unwrap_value (evaluate_subexp_standard
+                         (expect_type, exp, pos, noside));
+         return ada_to_fixed_value (VALUE_TYPE (arg1), 0,
+                                    VALUE_ADDRESS (arg1) +
+                                    VALUE_OFFSET (arg1), arg1);
+       }
+
+    case OP_ARRAY:
+      (*pos) += 3;
+      tem2 = longest_to_int (exp->elts[pc + 1].longconst);
+      tem3 = longest_to_int (exp->elts[pc + 2].longconst);
+      nargs = tem3 - tem2 + 1;
+      type = expect_type ? check_typedef (expect_type) : NULL_TYPE;
+
+      argvec =
+       (struct value * *) alloca (sizeof (struct value *) * (nargs + 1));
+      for (tem = 0; tem == 0 || tem < nargs; tem += 1)
+       /* At least one element gets inserted for the type */
+       {
+         /* Ensure that array expressions are coerced into pointer objects. */
+         argvec[tem] = evaluate_subexp_with_coercion (exp, pos, noside);
+       }
+      if (noside == EVAL_SKIP)
+       goto nosideret;
+      return value_array (tem2, tem3, argvec);
+
+    case OP_FUNCALL:
+      (*pos) += 2;
+
+      /* Allocate arg vector, including space for the function to be
+         called in argvec[0] and a terminating NULL */
+      nargs = longest_to_int (exp->elts[pc + 1].longconst);
+      argvec =
+       (struct value * *) alloca (sizeof (struct value *) * (nargs + 2));
+
+      /* FIXME: OP_UNRESOLVED_VALUE should be defined in expression.h */
+      /* FIXME: name should be defined in expresion.h */
+      /*      if (exp->elts[*pos].opcode == OP_UNRESOLVED_VALUE)
+         error ("Unexpected unresolved symbol, %s, during evaluation",
+         ada_demangle (exp->elts[pc + 5].name));
+       */
+      if (0)
+       {
+         error ("unexpected code path, FIXME");
+       }
+      else
+       {
+         for (tem = 0; tem <= nargs; tem += 1)
+           argvec[tem] = evaluate_subexp (NULL_TYPE, exp, pos, noside);
+         argvec[tem] = 0;
+
+         if (noside == EVAL_SKIP)
+           goto nosideret;
+       }
+
+      if (TYPE_CODE (VALUE_TYPE (argvec[0])) == TYPE_CODE_REF)
+       argvec[0] = value_addr (argvec[0]);
+
+      if (ada_is_packed_array_type (VALUE_TYPE (argvec[0])))
+       argvec[0] = ada_coerce_to_simple_array (argvec[0]);
+
+      type = check_typedef (VALUE_TYPE (argvec[0]));
+      if (TYPE_CODE (type) == TYPE_CODE_PTR)
+       {
+         switch (TYPE_CODE (check_typedef (TYPE_TARGET_TYPE (type))))
+           {
+           case TYPE_CODE_FUNC:
+             type = check_typedef (TYPE_TARGET_TYPE (type));
+             break;
+           case TYPE_CODE_ARRAY:
+             break;
+           case TYPE_CODE_STRUCT:
+             if (noside != EVAL_AVOID_SIDE_EFFECTS)
+               argvec[0] = ada_value_ind (argvec[0]);
+             type = check_typedef (TYPE_TARGET_TYPE (type));
+             break;
+           default:
+             error ("cannot subscript or call something of type `%s'",
+                    ada_type_name (VALUE_TYPE (argvec[0])));
+             break;
+           }
+       }
+
+      switch (TYPE_CODE (type))
+       {
+       case TYPE_CODE_FUNC:
+         if (noside == EVAL_AVOID_SIDE_EFFECTS)
+           return allocate_value (TYPE_TARGET_TYPE (type));
+         return call_function_by_hand (argvec[0], nargs, argvec + 1);
+       case TYPE_CODE_STRUCT:
+         {
+           int arity = ada_array_arity (type);
+           type = ada_array_element_type (type, nargs);
+           if (type == NULL)
+             error ("cannot subscript or call a record");
+           if (arity != nargs)
+             error ("wrong number of subscripts; expecting %d", arity);
+           if (noside == EVAL_AVOID_SIDE_EFFECTS)
+             return allocate_value (ada_aligned_type (type));
+           return
+             unwrap_value (ada_value_subscript
+                           (argvec[0], nargs, argvec + 1));
+         }
+       case TYPE_CODE_ARRAY:
+         if (noside == EVAL_AVOID_SIDE_EFFECTS)
+           {
+             type = ada_array_element_type (type, nargs);
+             if (type == NULL)
+               error ("element type of array unknown");
+             else
+               return allocate_value (ada_aligned_type (type));
+           }
+         return
+           unwrap_value (ada_value_subscript
+                         (ada_coerce_to_simple_array (argvec[0]),
+                          nargs, argvec + 1));
+       case TYPE_CODE_PTR:     /* Pointer to array */
+         type = to_fixed_array_type (TYPE_TARGET_TYPE (type), NULL, 1);
+         if (noside == EVAL_AVOID_SIDE_EFFECTS)
+           {
+             type = ada_array_element_type (type, nargs);
+             if (type == NULL)
+               error ("element type of array unknown");
+             else
+               return allocate_value (ada_aligned_type (type));
+           }
+         return
+           unwrap_value (ada_value_ptr_subscript (argvec[0], type,
+                                                  nargs, argvec + 1));
+
+       default:
+         error ("Internal error in evaluate_subexp");
+       }
+
+    case TERNOP_SLICE:
+      {
+       struct value *array = evaluate_subexp (NULL_TYPE, exp, pos, noside);
+       int lowbound
+         = value_as_long (evaluate_subexp (NULL_TYPE, exp, pos, noside));
+       int upper
+         = value_as_long (evaluate_subexp (NULL_TYPE, exp, pos, noside));
+       if (noside == EVAL_SKIP)
+         goto nosideret;
+
+       /* If this is a reference to an array, then dereference it */
+       if (TYPE_CODE (VALUE_TYPE (array)) == TYPE_CODE_REF
+           && TYPE_TARGET_TYPE (VALUE_TYPE (array)) != NULL
+           && TYPE_CODE (TYPE_TARGET_TYPE (VALUE_TYPE (array))) ==
+           TYPE_CODE_ARRAY
+           && !ada_is_array_descriptor (check_typedef (VALUE_TYPE (array))))
+         {
+           array = ada_coerce_ref (array);
+         }
+
+       if (noside == EVAL_AVOID_SIDE_EFFECTS &&
+           ada_is_array_descriptor (check_typedef (VALUE_TYPE (array))))
+         {
+           /* Try to dereference the array, in case it is an access to array */
+           struct type *arrType = ada_type_of_array (array, 0);
+           if (arrType != NULL)
+             array = value_at_lazy (arrType, 0, NULL);
+         }
+       if (ada_is_array_descriptor (VALUE_TYPE (array)))
+         array = ada_coerce_to_simple_array (array);
+
+       /* If at this point we have a pointer to an array, it means that
+          it is a pointer to a simple (non-ada) array. We just then
+          dereference it */
+       if (TYPE_CODE (VALUE_TYPE (array)) == TYPE_CODE_PTR
+           && TYPE_TARGET_TYPE (VALUE_TYPE (array)) != NULL
+           && TYPE_CODE (TYPE_TARGET_TYPE (VALUE_TYPE (array))) ==
+           TYPE_CODE_ARRAY)
+         {
+           array = ada_value_ind (array);
+         }
+
+       if (noside == EVAL_AVOID_SIDE_EFFECTS)
+         /* The following will get the bounds wrong, but only in contexts
+            where the value is not being requested (FIXME?). */
+         return array;
+       else
+         return value_slice (array, lowbound, upper - lowbound + 1);
+      }
+
+      /* FIXME: UNOP_MBR should be defined in expression.h */
+      /*    case UNOP_MBR:
+         (*pos) += 2;
+         arg1 = evaluate_subexp (NULL_TYPE, exp, pos, noside);
+         type = exp->elts[pc + 1].type;
+
+         if (noside == EVAL_SKIP)
+         goto nosideret;
+
+         switch (TYPE_CODE (type)) 
+         {
+         default:
+         warning ("Membership test incompletely implemented; always returns true");
+         return value_from_longest (builtin_type_int, (LONGEST) 1);
+
+         case TYPE_CODE_RANGE:
+         arg2 = value_from_longest (builtin_type_int, 
+         (LONGEST) TYPE_LOW_BOUND (type));
+         arg3 = value_from_longest (builtin_type_int, 
+         (LONGEST) TYPE_HIGH_BOUND (type));
+         return 
+         value_from_longest (builtin_type_int,
+         (value_less (arg1,arg3) 
+         || value_equal (arg1,arg3))
+         && (value_less (arg2,arg1)
+         || value_equal (arg2,arg1)));
+         }
+       */
+      /* FIXME: BINOP_MBR should be defined in expression.h */
+      /*    case BINOP_MBR:
+         (*pos) += 2;
+         arg1 = evaluate_subexp (NULL_TYPE, exp, pos, noside);
+         arg2 = evaluate_subexp (NULL_TYPE, exp, pos, noside);
+
+         if (noside == EVAL_SKIP)
+         goto nosideret;
+
+         if (noside == EVAL_AVOID_SIDE_EFFECTS)
+         return value_zero (builtin_type_int, not_lval);
+
+         tem = longest_to_int (exp->elts[pc + 1].longconst);
+
+         if (tem < 1 || tem > ada_array_arity (VALUE_TYPE (arg2)))
+         error ("invalid dimension number to '%s", "range");
+
+         arg3 = ada_array_bound (arg2, tem, 1);
+         arg2 = ada_array_bound (arg2, tem, 0);
+
+         return 
+         value_from_longest (builtin_type_int,
+         (value_less (arg1,arg3) 
+         || value_equal (arg1,arg3))
+         && (value_less (arg2,arg1)
+         || value_equal (arg2,arg1)));
+       */
+      /* FIXME: TERNOP_MBR should be defined in expression.h */
+      /*    case TERNOP_MBR:
+         arg1 = evaluate_subexp (NULL_TYPE, exp, pos, noside);
+         arg2 = evaluate_subexp (NULL_TYPE, exp, pos, noside);
+         arg3 = evaluate_subexp (NULL_TYPE, exp, pos, noside);
+
+         if (noside == EVAL_SKIP)
+         goto nosideret;
+
+         return 
+         value_from_longest (builtin_type_int,
+         (value_less (arg1,arg3) 
+         || value_equal (arg1,arg3))
+         && (value_less (arg2,arg1)
+         || value_equal (arg2,arg1)));
+       */
+      /* FIXME: OP_ATTRIBUTE should be defined in expression.h */
+      /*    case OP_ATTRIBUTE:
+         *pos += 3;
+         atr = (enum ada_attribute) longest_to_int (exp->elts[pc + 2].longconst);
+         switch (atr) 
+         {
+         default:
+         error ("unexpected attribute encountered");
+
+         case ATR_FIRST:
+         case ATR_LAST:
+         case ATR_LENGTH:
+         {
+         struct type* type_arg;
+         if (exp->elts[*pos].opcode == OP_TYPE)
+         {
+         evaluate_subexp (NULL_TYPE, exp, pos, EVAL_SKIP);
+         arg1 = NULL;
+         type_arg = exp->elts[pc + 5].type;
+         }
+         else
+         {
+         arg1 = evaluate_subexp (NULL_TYPE, exp, pos, noside);
+         type_arg = NULL;
+         }
+
+         if (exp->elts[*pos].opcode != OP_LONG) 
+         error ("illegal operand to '%s", ada_attribute_name (atr));
+         tem = longest_to_int (exp->elts[*pos+2].longconst);
+         *pos += 4;
+
+         if (noside == EVAL_SKIP)
+         goto nosideret;
+
+         if (type_arg == NULL)
+         {
+         arg1 = ada_coerce_ref (arg1);
+
+         if (ada_is_packed_array_type (VALUE_TYPE (arg1)))
+         arg1 = ada_coerce_to_simple_array (arg1);
+
+         if (tem < 1 || tem > ada_array_arity (VALUE_TYPE (arg1)))
+         error ("invalid dimension number to '%s", 
+         ada_attribute_name (atr));
+
+         if (noside == EVAL_AVOID_SIDE_EFFECTS)
+         {
+         type = ada_index_type (VALUE_TYPE (arg1), tem);
+         if (type == NULL) 
+         error ("attempt to take bound of something that is not an array");
+         return allocate_value (type);
+         }
+
+         switch (atr) 
+         {
+         default: 
+         error ("unexpected attribute encountered");
+         case ATR_FIRST:
+         return ada_array_bound (arg1, tem, 0);
+         case ATR_LAST:
+         return ada_array_bound (arg1, tem, 1);
+         case ATR_LENGTH:
+         return ada_array_length (arg1, tem);
+         }
+         }
+         else if (TYPE_CODE (type_arg) == TYPE_CODE_RANGE
+         || TYPE_CODE (type_arg) == TYPE_CODE_INT) 
+         {
+         struct type* range_type;
+         char* name = ada_type_name (type_arg);
+         if (name == NULL)
+         {
+         if (TYPE_CODE (type_arg) == TYPE_CODE_RANGE) 
+         range_type = type_arg;
+         else
+         error ("unimplemented type attribute");
+         }
+         else 
+         range_type = 
+         to_fixed_range_type (name, NULL, TYPE_OBJFILE (type_arg));
+         switch (atr) 
+         {
+         default: 
+         error ("unexpected attribute encountered");
+         case ATR_FIRST:
+         return value_from_longest (TYPE_TARGET_TYPE (range_type),
+         TYPE_LOW_BOUND (range_type));
+         case ATR_LAST:
+         return value_from_longest (TYPE_TARGET_TYPE (range_type),
+         TYPE_HIGH_BOUND (range_type));
+         }
+         }              
+         else if (TYPE_CODE (type_arg) == TYPE_CODE_ENUM)
+         {
+         switch (atr) 
+         {
+         default: 
+         error ("unexpected attribute encountered");
+         case ATR_FIRST:
+         return value_from_longest 
+         (type_arg, TYPE_FIELD_BITPOS (type_arg, 0));
+         case ATR_LAST:
+         return value_from_longest 
+         (type_arg, 
+         TYPE_FIELD_BITPOS (type_arg,
+         TYPE_NFIELDS (type_arg) - 1));
+         }
+         }
+         else if (TYPE_CODE (type_arg) == TYPE_CODE_FLT)
+         error ("unimplemented type attribute");
+         else 
+         {
+         LONGEST low, high;
+
+         if (ada_is_packed_array_type (type_arg))
+         type_arg = decode_packed_array_type (type_arg);
+
+         if (tem < 1 || tem > ada_array_arity (type_arg))
+         error ("invalid dimension number to '%s", 
+         ada_attribute_name (atr));
+
+         if (noside == EVAL_AVOID_SIDE_EFFECTS)
+         {
+         type = ada_index_type (type_arg, tem);
+         if (type == NULL) 
+         error ("attempt to take bound of something that is not an array");
+         return allocate_value (type);
+         }
+
+         switch (atr) 
+         {
+         default: 
+         error ("unexpected attribute encountered");
+         case ATR_FIRST:
+         low = ada_array_bound_from_type (type_arg, tem, 0, &type);
+         return value_from_longest (type, low);
+         case ATR_LAST:
+         high = ada_array_bound_from_type (type_arg, tem, 1, &type);
+         return value_from_longest (type, high);
+         case ATR_LENGTH:
+         low = ada_array_bound_from_type (type_arg, tem, 0, &type);
+         high = ada_array_bound_from_type (type_arg, tem, 1, NULL);
+         return value_from_longest (type, high-low+1);
+         }
+         }
+         }
+
+         case ATR_TAG:
+         arg1 = evaluate_subexp (NULL_TYPE, exp, pos, noside);
+         if (noside == EVAL_SKIP)
+         goto nosideret;
+
+         if (noside == EVAL_AVOID_SIDE_EFFECTS)
+         return         
+         value_zero (ada_tag_type (arg1), not_lval);
+
+         return ada_value_tag (arg1);
+
+         case ATR_MIN:
+         case ATR_MAX:
+         evaluate_subexp (NULL_TYPE, exp, pos, EVAL_SKIP);
+         arg1 = evaluate_subexp (NULL_TYPE, exp, pos, noside);
+         arg2 = evaluate_subexp (NULL_TYPE, exp, pos, noside);
+         if (noside == EVAL_SKIP)
+         goto nosideret;
+         else if (noside == EVAL_AVOID_SIDE_EFFECTS)
+         return value_zero (VALUE_TYPE (arg1), not_lval);
+         else
+         return value_binop (arg1, arg2, 
+         atr == ATR_MIN ? BINOP_MIN : BINOP_MAX);
+
+         case ATR_MODULUS:
+         {
+         struct type* type_arg = exp->elts[pc + 5].type;
+         evaluate_subexp (NULL_TYPE, exp, pos, EVAL_SKIP);
+         *pos += 4;
+
+         if (noside == EVAL_SKIP)
+         goto nosideret;
+
+         if (! ada_is_modular_type (type_arg))
+         error ("'modulus must be applied to modular type");
+
+         return value_from_longest (TYPE_TARGET_TYPE (type_arg),
+         ada_modulus (type_arg));
+         }
+
+
+         case ATR_POS:
+         evaluate_subexp (NULL_TYPE, exp, pos, EVAL_SKIP);
+         arg1 = evaluate_subexp (NULL_TYPE, exp, pos, noside);
+         if (noside == EVAL_SKIP)
+         goto nosideret;
+         else if (noside == EVAL_AVOID_SIDE_EFFECTS)
+         return value_zero (builtin_type_ada_int, not_lval);
+         else 
+         return value_pos_atr (arg1);
+
+         case ATR_SIZE:
+         arg1 = evaluate_subexp (NULL_TYPE, exp, pos, noside);
+         if (noside == EVAL_SKIP)
+         goto nosideret;
+         else if (noside == EVAL_AVOID_SIDE_EFFECTS)
+         return value_zero (builtin_type_ada_int, not_lval);
+         else
+         return value_from_longest (builtin_type_ada_int,
+         TARGET_CHAR_BIT 
+         * TYPE_LENGTH (VALUE_TYPE (arg1)));
+
+         case ATR_VAL:
+         evaluate_subexp (NULL_TYPE, exp, pos, EVAL_SKIP);
+         arg1 = evaluate_subexp (NULL_TYPE, exp, pos, noside);
+         type = exp->elts[pc + 5].type;
+         if (noside == EVAL_SKIP)
+         goto nosideret;
+         else if (noside == EVAL_AVOID_SIDE_EFFECTS)
+         return value_zero (type, not_lval);
+         else 
+         return value_val_atr (type, arg1);
+         } */
+    case BINOP_EXP:
+      arg1 = evaluate_subexp (NULL_TYPE, exp, pos, noside);
+      arg2 = evaluate_subexp (NULL_TYPE, exp, pos, noside);
+      if (noside == EVAL_SKIP)
+       goto nosideret;
+      if (binop_user_defined_p (op, arg1, arg2))
+       return unwrap_value (value_x_binop (arg1, arg2, op, OP_NULL,
+                                           EVAL_NORMAL));
+      else if (noside == EVAL_AVOID_SIDE_EFFECTS)
+       return value_zero (VALUE_TYPE (arg1), not_lval);
+      else
+       return value_binop (arg1, arg2, op);
+
+    case UNOP_PLUS:
+      arg1 = evaluate_subexp (NULL_TYPE, exp, pos, noside);
+      if (noside == EVAL_SKIP)
+       goto nosideret;
+      if (unop_user_defined_p (op, arg1))
+       return unwrap_value (value_x_unop (arg1, op, EVAL_NORMAL));
+      else
+       return arg1;
+
+    case UNOP_ABS:
+      arg1 = evaluate_subexp (NULL_TYPE, exp, pos, noside);
+      if (noside == EVAL_SKIP)
+       goto nosideret;
+      if (value_less (arg1, value_zero (VALUE_TYPE (arg1), not_lval)))
+       return value_neg (arg1);
+      else
+       return arg1;
+
+    case UNOP_IND:
+      if (expect_type && TYPE_CODE (expect_type) == TYPE_CODE_PTR)
+       expect_type = TYPE_TARGET_TYPE (check_typedef (expect_type));
+      arg1 = evaluate_subexp (expect_type, exp, pos, noside);
+      if (noside == EVAL_SKIP)
+       goto nosideret;
+      type = check_typedef (VALUE_TYPE (arg1));
+      if (noside == EVAL_AVOID_SIDE_EFFECTS)
+       {
+         if (ada_is_array_descriptor (type))
+           /* GDB allows dereferencing GNAT array descriptors. */
+           {
+             struct type *arrType = ada_type_of_array (arg1, 0);
+             if (arrType == NULL)
+               error ("Attempt to dereference null array pointer.");
+             return value_at_lazy (arrType, 0, NULL);
+           }
+         else if (TYPE_CODE (type) == TYPE_CODE_PTR
+                  || TYPE_CODE (type) == TYPE_CODE_REF
+                  /* In C you can dereference an array to get the 1st elt.  */
+                  || TYPE_CODE (type) == TYPE_CODE_ARRAY)
+           return
+             value_zero
+             (to_static_fixed_type
+              (ada_aligned_type (check_typedef (TYPE_TARGET_TYPE (type)))),
+              lval_memory);
+         else if (TYPE_CODE (type) == TYPE_CODE_INT)
+           /* GDB allows dereferencing an int.  */
+           return value_zero (builtin_type_int, lval_memory);
+         else
+           error ("Attempt to take contents of a non-pointer value.");
+       }
+      arg1 = ada_coerce_ref (arg1);
+      type = check_typedef (VALUE_TYPE (arg1));
+
+      if (ada_is_array_descriptor (type))
+       /* GDB allows dereferencing GNAT array descriptors. */
+       return ada_coerce_to_simple_array (arg1);
+      else
+       return ada_value_ind (arg1);
+
+    case STRUCTOP_STRUCT:
+      tem = longest_to_int (exp->elts[pc + 1].longconst);
+      (*pos) += 3 + BYTES_TO_EXP_ELEM (tem + 1);
+      arg1 = evaluate_subexp (NULL_TYPE, exp, pos, noside);
+      if (noside == EVAL_SKIP)
+       goto nosideret;
+      if (noside == EVAL_AVOID_SIDE_EFFECTS)
+       return value_zero (ada_aligned_type
+                          (ada_lookup_struct_elt_type (VALUE_TYPE (arg1),
+                                                       &exp->elts[pc +
+                                                                  2].string,
+                                                       0, NULL)),
+                          lval_memory);
+      else
+       return unwrap_value (ada_value_struct_elt (arg1,
+                                                  &exp->elts[pc + 2].string,
+                                                  "record"));
+    case OP_TYPE:
+      /* The value is not supposed to be used. This is here to make it
+         easier to accommodate expressions that contain types. */
+      (*pos) += 2;
+      if (noside == EVAL_SKIP)
+       goto nosideret;
+      else if (noside == EVAL_AVOID_SIDE_EFFECTS)
+       return allocate_value (builtin_type_void);
+      else
+       error ("Attempt to use a type name as an expression");
+
+    case STRUCTOP_PTR:
+      tem = longest_to_int (exp->elts[pc + 1].longconst);
+      (*pos) += 3 + BYTES_TO_EXP_ELEM (tem + 1);
+      arg1 = evaluate_subexp (NULL_TYPE, exp, pos, noside);
+      if (noside == EVAL_SKIP)
+       goto nosideret;
+      if (noside == EVAL_AVOID_SIDE_EFFECTS)
+       return value_zero (ada_aligned_type
+                          (ada_lookup_struct_elt_type (VALUE_TYPE (arg1),
+                                                       &exp->elts[pc +
+                                                                  2].string,
+                                                       0, NULL)),
+                          lval_memory);
+      else
+       return unwrap_value (ada_value_struct_elt (arg1,
+                                                  &exp->elts[pc + 2].string,
+                                                  "record access"));
+    }
+
+nosideret:
+  return value_from_longest (builtin_type_long, (LONGEST) 1);
+}
+\f
+
+                               /* Fixed point */
+
+/* If TYPE encodes an Ada fixed-point type, return the suffix of the
+   type name that encodes the 'small and 'delta information.
+   Otherwise, return NULL. */
+
+static const char *
+fixed_type_info (struct type *type)
+{
+  const char *name = ada_type_name (type);
+  enum type_code code = (type == NULL) ? TYPE_CODE_UNDEF : TYPE_CODE (type);
+
+  if ((code == TYPE_CODE_INT || code == TYPE_CODE_RANGE) && name != NULL)
+    {
+      const char *tail = strstr (name, "___XF_");
+      if (tail == NULL)
+       return NULL;
+      else
+       return tail + 5;
+    }
+  else if (code == TYPE_CODE_RANGE && TYPE_TARGET_TYPE (type) != type)
+    return fixed_type_info (TYPE_TARGET_TYPE (type));
+  else
+    return NULL;
+}
+
+/* Returns non-zero iff TYPE represents an Ada fixed-point type. */
+
+int
+ada_is_fixed_point_type (struct type *type)
+{
+  return fixed_type_info (type) != NULL;
+}
+
+/* Assuming that TYPE is the representation of an Ada fixed-point
+   type, return its delta, or -1 if the type is malformed and the
+   delta cannot be determined. */
+
+DOUBLEST
+ada_delta (struct type *type)
+{
+  const char *encoding = fixed_type_info (type);
+  long num, den;
+
+  if (sscanf (encoding, "_%ld_%ld", &num, &den) < 2)
+    return -1.0;
+  else
+    return (DOUBLEST) num / (DOUBLEST) den;
+}
+
+/* Assuming that ada_is_fixed_point_type (TYPE), return the scaling
+   factor ('SMALL value) associated with the type. */
+
+static DOUBLEST
+scaling_factor (struct type *type)
+{
+  const char *encoding = fixed_type_info (type);
+  unsigned long num0, den0, num1, den1;
+  int n;
+
+  n = sscanf (encoding, "_%lu_%lu_%lu_%lu", &num0, &den0, &num1, &den1);
+
+  if (n < 2)
+    return 1.0;
+  else if (n == 4)
+    return (DOUBLEST) num1 / (DOUBLEST) den1;
+  else
+    return (DOUBLEST) num0 / (DOUBLEST) den0;
+}
+
+
+/* Assuming that X is the representation of a value of fixed-point
+   type TYPE, return its floating-point equivalent. */
+
+DOUBLEST
+ada_fixed_to_float (struct type *type, LONGEST x)
+{
+  return (DOUBLEST) x *scaling_factor (type);
+}
+
+/* The representation of a fixed-point value of type TYPE 
+   corresponding to the value X. */
+
+LONGEST
+ada_float_to_fixed (struct type *type, DOUBLEST x)
+{
+  return (LONGEST) (x / scaling_factor (type) + 0.5);
+}
+
+
+                               /* VAX floating formats */
+
+/* Non-zero iff TYPE represents one of the special VAX floating-point
+   types. */
+int
+ada_is_vax_floating_type (struct type *type)
+{
+  int name_len =
+    (ada_type_name (type) == NULL) ? 0 : strlen (ada_type_name (type));
+  return
+    name_len > 6
+    && (TYPE_CODE (type) == TYPE_CODE_INT
+       || TYPE_CODE (type) == TYPE_CODE_RANGE)
+    && STREQN (ada_type_name (type) + name_len - 6, "___XF", 5);
+}
+
+/* The type of special VAX floating-point type this is, assuming
+   ada_is_vax_floating_point */
+int
+ada_vax_float_type_suffix (struct type *type)
+{
+  return ada_type_name (type)[strlen (ada_type_name (type)) - 1];
+}
+
+/* A value representing the special debugging function that outputs 
+   VAX floating-point values of the type represented by TYPE.  Assumes
+   ada_is_vax_floating_type (TYPE). */
+struct value *
+ada_vax_float_print_function (struct type *type)
+{
+  switch (ada_vax_float_type_suffix (type))
+    {
+    case 'F':
+      return get_var_value ("DEBUG_STRING_F", 0);
+    case 'D':
+      return get_var_value ("DEBUG_STRING_D", 0);
+    case 'G':
+      return get_var_value ("DEBUG_STRING_G", 0);
+    default:
+      error ("invalid VAX floating-point type");
+    }
+}
+\f
+
+                               /* Range types */
+
+/* Scan STR beginning at position K for a discriminant name, and
+   return the value of that discriminant field of DVAL in *PX.  If
+   PNEW_K is not null, put the position of the character beyond the
+   name scanned in *PNEW_K.  Return 1 if successful; return 0 and do
+   not alter *PX and *PNEW_K if unsuccessful. */
+
+static int
+scan_discrim_bound (char *, int k, struct value *dval, LONGEST * px,
+                   int *pnew_k)
+{
+  static char *bound_buffer = NULL;
+  static size_t bound_buffer_len = 0;
+  char *bound;
+  char *pend;
+  struct value *bound_val;
+
+  if (dval == NULL || str == NULL || str[k] == '\0')
+    return 0;
+
+  pend = strstr (str + k, "__");
+  if (pend == NULL)
+    {
+      bound = str + k;
+      k += strlen (bound);
+    }
+  else
+    {
+      GROW_VECT (bound_buffer, bound_buffer_len, pend - (str + k) + 1);
+      bound = bound_buffer;
+      strncpy (bound_buffer, str + k, pend - (str + k));
+      bound[pend - (str + k)] = '\0';
+      k = pend - str;
+    }
+
+  bound_val = ada_search_struct_field (bound, dval, 0, VALUE_TYPE (dval));
+  if (bound_val == NULL)
+    return 0;
+
+  *px = value_as_long (bound_val);
+  if (pnew_k != NULL)
+    *pnew_k = k;
+  return 1;
+}
+
+/* Value of variable named NAME in the current environment.  If
+   no such variable found, then if ERR_MSG is null, returns 0, and
+   otherwise causes an error with message ERR_MSG. */
+static struct value *
+get_var_value (char *name, char *err_msg)
+{
+  struct symbol **syms;
+  struct block **blocks;
+  int nsyms;
+
+  nsyms =
+    ada_lookup_symbol_list (name, get_selected_block (NULL), VAR_NAMESPACE,
+                           &syms, &blocks);
+
+  if (nsyms != 1)
+    {
+      if (err_msg == NULL)
+       return 0;
+      else
+       error ("%s", err_msg);
+    }
+
+  return value_of_variable (syms[0], blocks[0]);
+}
+
+/* Value of integer variable named NAME in the current environment.  If
+   no such variable found, then if ERR_MSG is null, returns 0, and sets
+   *FLAG to 0.  If successful, sets *FLAG to 1. */
+LONGEST
+get_int_var_value (char *name, char *err_msg, int *flag)
+{
+  struct value *var_val = get_var_value (name, err_msg);
+
+  if (var_val == 0)
+    {
+      if (flag != NULL)
+       *flag = 0;
+      return 0;
+    }
+  else
+    {
+      if (flag != NULL)
+       *flag = 1;
+      return value_as_long (var_val);
+    }
+}
+
+
+/* Return a range type whose base type is that of the range type named
+   NAME in the current environment, and whose bounds are calculated
+   from NAME according to the GNAT range encoding conventions. 
+   Extract discriminant values, if needed, from DVAL.  If a new type
+   must be created, allocate in OBJFILE's space.  The bounds
+   information, in general, is encoded in NAME, the base type given in
+   the named range type. */
+
+static struct type *
+to_fixed_range_type (char *name, struct value *dval, struct objfile *objfile)
+{
+  struct type *raw_type = ada_find_any_type (name);
+  struct type *base_type;
+  LONGEST low, high;
+  char *subtype_info;
+
+  if (raw_type == NULL)
+    base_type = builtin_type_int;
+  else if (TYPE_CODE (raw_type) == TYPE_CODE_RANGE)
+    base_type = TYPE_TARGET_TYPE (raw_type);
+  else
+    base_type = raw_type;
+
+  subtype_info = strstr (name, "___XD");
+  if (subtype_info == NULL)
+    return raw_type;
+  else
+    {
+      static char *name_buf = NULL;
+      static size_t name_len = 0;
+      int prefix_len = subtype_info - name;
+      LONGEST L, U;
+      struct type *type;
+      char *bounds_str;
+      int n;
+
+      GROW_VECT (name_buf, name_len, prefix_len + 5);
+      strncpy (name_buf, name, prefix_len);
+      name_buf[prefix_len] = '\0';
+
+      subtype_info += 5;
+      bounds_str = strchr (subtype_info, '_');
+      n = 1;
+
+      if (*subtype_info == 'L')
+       {
+         if (!ada_scan_number (bounds_str, n, &L, &n)
+             && !scan_discrim_bound (bounds_str, n, dval, &L, &n))
+           return raw_type;
+         if (bounds_str[n] == '_')
+           n += 2;
+         else if (bounds_str[n] == '.')        /* FIXME? SGI Workshop kludge. */
+           n += 1;
+         subtype_info += 1;
+       }
+      else
+       {
+         strcpy (name_buf + prefix_len, "___L");
+         L = get_int_var_value (name_buf, "Index bound unknown.", NULL);
+       }
+
+      if (*subtype_info == 'U')
+       {
+         if (!ada_scan_number (bounds_str, n, &U, &n)
+             && !scan_discrim_bound (bounds_str, n, dval, &U, &n))
+           return raw_type;
+       }
+      else
+       {
+         strcpy (name_buf + prefix_len, "___U");
+         U = get_int_var_value (name_buf, "Index bound unknown.", NULL);
+       }
+
+      if (objfile == NULL)
+       objfile = TYPE_OBJFILE (base_type);
+      type = create_range_type (alloc_type (objfile), base_type, L, U);
+      TYPE_NAME (type) = name;
+      return type;
+    }
+}
+
+/* True iff NAME is the name of a range type. */
+int
+ada_is_range_type_name (const char *name)
+{
+  return (name != NULL && strstr (name, "___XD"));
+}
+\f
+
+                               /* Modular types */
+
+/* True iff TYPE is an Ada modular type. */
+int
+ada_is_modular_type (struct type *type)
+{
+  /* FIXME: base_type should be declared in gdbtypes.h, implemented in
+     valarith.c */
+  struct type *subranged_type; /* = base_type (type); */
+
+  return (subranged_type != NULL && TYPE_CODE (type) == TYPE_CODE_RANGE
+         && TYPE_CODE (subranged_type) != TYPE_CODE_ENUM
+         && TYPE_UNSIGNED (subranged_type));
+}
+
+/* Assuming ada_is_modular_type (TYPE), the modulus of TYPE. */
+LONGEST
+ada_modulus (struct type * type)
+{
+  return TYPE_HIGH_BOUND (type) + 1;
+}
+\f
+
+
+                               /* Operators */
+
+/* Table mapping opcodes into strings for printing operators
+   and precedences of the operators.  */
+
+static const struct op_print ada_op_print_tab[] = {
+  {":=", BINOP_ASSIGN, PREC_ASSIGN, 1},
+  {"or else", BINOP_LOGICAL_OR, PREC_LOGICAL_OR, 0},
+  {"and then", BINOP_LOGICAL_AND, PREC_LOGICAL_AND, 0},
+  {"or", BINOP_BITWISE_IOR, PREC_BITWISE_IOR, 0},
+  {"xor", BINOP_BITWISE_XOR, PREC_BITWISE_XOR, 0},
+  {"and", BINOP_BITWISE_AND, PREC_BITWISE_AND, 0},
+  {"=", BINOP_EQUAL, PREC_EQUAL, 0},
+  {"/=", BINOP_NOTEQUAL, PREC_EQUAL, 0},
+  {"<=", BINOP_LEQ, PREC_ORDER, 0},
+  {">=", BINOP_GEQ, PREC_ORDER, 0},
+  {">", BINOP_GTR, PREC_ORDER, 0},
+  {"<", BINOP_LESS, PREC_ORDER, 0},
+  {">>", BINOP_RSH, PREC_SHIFT, 0},
+  {"<<", BINOP_LSH, PREC_SHIFT, 0},
+  {"+", BINOP_ADD, PREC_ADD, 0},
+  {"-", BINOP_SUB, PREC_ADD, 0},
+  {"&", BINOP_CONCAT, PREC_ADD, 0},
+  {"*", BINOP_MUL, PREC_MUL, 0},
+  {"/", BINOP_DIV, PREC_MUL, 0},
+  {"rem", BINOP_REM, PREC_MUL, 0},
+  {"mod", BINOP_MOD, PREC_MUL, 0},
+  {"**", BINOP_EXP, PREC_REPEAT, 0},
+  {"@", BINOP_REPEAT, PREC_REPEAT, 0},
+  {"-", UNOP_NEG, PREC_PREFIX, 0},
+  {"+", UNOP_PLUS, PREC_PREFIX, 0},
+  {"not ", UNOP_LOGICAL_NOT, PREC_PREFIX, 0},
+  {"not ", UNOP_COMPLEMENT, PREC_PREFIX, 0},
+  {"abs ", UNOP_ABS, PREC_PREFIX, 0},
+  {".all", UNOP_IND, PREC_SUFFIX, 1},  /* FIXME: postfix .ALL */
+  {"'access", UNOP_ADDR, PREC_SUFFIX, 1},      /* FIXME: postfix 'ACCESS */
+  {NULL, 0, 0, 0}
+};
+\f
+                       /* Assorted Types and Interfaces */
+
+struct type *builtin_type_ada_int;
+struct type *builtin_type_ada_short;
+struct type *builtin_type_ada_long;
+struct type *builtin_type_ada_long_long;
+struct type *builtin_type_ada_char;
+struct type *builtin_type_ada_float;
+struct type *builtin_type_ada_double;
+struct type *builtin_type_ada_long_double;
+struct type *builtin_type_ada_natural;
+struct type *builtin_type_ada_positive;
+struct type *builtin_type_ada_system_address;
+
+struct type **const (ada_builtin_types[]) =
+{
+
+  &builtin_type_ada_int,
+    &builtin_type_ada_long,
+    &builtin_type_ada_short,
+    &builtin_type_ada_char,
+    &builtin_type_ada_float,
+    &builtin_type_ada_double,
+    &builtin_type_ada_long_long,
+    &builtin_type_ada_long_double,
+    &builtin_type_ada_natural, &builtin_type_ada_positive,
+    /* The following types are carried over from C for convenience. */
+&builtin_type_int,
+    &builtin_type_long,
+    &builtin_type_short,
+    &builtin_type_char,
+    &builtin_type_float,
+    &builtin_type_double,
+    &builtin_type_long_long,
+    &builtin_type_void,
+    &builtin_type_signed_char,
+    &builtin_type_unsigned_char,
+    &builtin_type_unsigned_short,
+    &builtin_type_unsigned_int,
+    &builtin_type_unsigned_long,
+    &builtin_type_unsigned_long_long,
+    &builtin_type_long_double,
+    &builtin_type_complex, &builtin_type_double_complex, 0};
+
+/* Not really used, but needed in the ada_language_defn. */
+static void
+emit_char (int c, struct ui_file *stream, int quoter)
+{
+  ada_emit_char (c, stream, quoter, 1);
+}
+
+const struct language_defn ada_language_defn = {
+  "ada",                       /* Language name */
+  /*  language_ada, */
+  language_unknown,
+  /* FIXME: language_ada should be defined in defs.h */
+  ada_builtin_types,
+  range_check_off,
+  type_check_off,
+  case_sensitive_on,           /* Yes, Ada is case-insensitive, but
+                                * that's not quite what this means. */
+  ada_parse,
+  ada_error,
+  ada_evaluate_subexp,
+  ada_printchar,               /* Print a character constant */
+  ada_printstr,                        /* Function to print string constant */
+  emit_char,                   /* Function to print single char (not used) */
+  ada_create_fundamental_type, /* Create fundamental type in this language */
+  ada_print_type,              /* Print a type using appropriate syntax */
+  ada_val_print,               /* Print a value using appropriate syntax */
+  ada_value_print,             /* Print a top-level value */
+  {"", "", "", ""},            /* Binary format info */
+#if 0
+  {"8#%lo#", "8#", "o", "#"},  /* Octal format info */
+  {"%ld", "", "d", ""},                /* Decimal format info */
+  {"16#%lx#", "16#", "x", "#"},        /* Hex format info */
+#else
+  /* Copied from c-lang.c. */
+  {"0%lo", "0", "o", ""},      /* Octal format info */
+  {"%ld", "", "d", ""},                /* Decimal format info */
+  {"0x%lx", "0x", "x", ""},    /* Hex format info */
+#endif
+  ada_op_print_tab,            /* expression operators for printing */
+  1,                           /* c-style arrays (FIXME?) */
+  0,                           /* String lower bound (FIXME?) */
+  &builtin_type_ada_char,
+  LANG_MAGIC
+};
+
+void
+_initialize_ada_language (void)
+{
+  builtin_type_ada_int =
+    init_type (TYPE_CODE_INT, TARGET_INT_BIT / TARGET_CHAR_BIT,
+              0, "integer", (struct objfile *) NULL);
+  builtin_type_ada_long =
+    init_type (TYPE_CODE_INT, TARGET_LONG_BIT / TARGET_CHAR_BIT,
+              0, "long_integer", (struct objfile *) NULL);
+  builtin_type_ada_short =
+    init_type (TYPE_CODE_INT, TARGET_SHORT_BIT / TARGET_CHAR_BIT,
+              0, "short_integer", (struct objfile *) NULL);
+  builtin_type_ada_char =
+    init_type (TYPE_CODE_INT, TARGET_CHAR_BIT / TARGET_CHAR_BIT,
+              0, "character", (struct objfile *) NULL);
+  builtin_type_ada_float =
+    init_type (TYPE_CODE_FLT, TARGET_FLOAT_BIT / TARGET_CHAR_BIT,
+              0, "float", (struct objfile *) NULL);
+  builtin_type_ada_double =
+    init_type (TYPE_CODE_FLT, TARGET_DOUBLE_BIT / TARGET_CHAR_BIT,
+              0, "long_float", (struct objfile *) NULL);
+  builtin_type_ada_long_long =
+    init_type (TYPE_CODE_INT, TARGET_LONG_LONG_BIT / TARGET_CHAR_BIT,
+              0, "long_long_integer", (struct objfile *) NULL);
+  builtin_type_ada_long_double =
+    init_type (TYPE_CODE_FLT, TARGET_LONG_DOUBLE_BIT / TARGET_CHAR_BIT,
+              0, "long_long_float", (struct objfile *) NULL);
+  builtin_type_ada_natural =
+    init_type (TYPE_CODE_INT, TARGET_INT_BIT / TARGET_CHAR_BIT,
+              0, "natural", (struct objfile *) NULL);
+  builtin_type_ada_positive =
+    init_type (TYPE_CODE_INT, TARGET_INT_BIT / TARGET_CHAR_BIT,
+              0, "positive", (struct objfile *) NULL);
+
+
+  builtin_type_ada_system_address =
+    lookup_pointer_type (init_type (TYPE_CODE_VOID, 1, 0, "void",
+                                   (struct objfile *) NULL));
+  TYPE_NAME (builtin_type_ada_system_address) = "system__address";
+
+  add_language (&ada_language_defn);
+
+  add_show_from_set
+    (add_set_cmd ("varsize-limit", class_support, var_uinteger,
+                 (char *) &varsize_limit,
+                 "Set maximum bytes in dynamic-sized object.",
+                 &setlist), &showlist);
+  varsize_limit = 65536;
+
+  add_com ("begin", class_breakpoint, begin_command,
+          "Start the debugged program, stopping at the beginning of the\n\
+main program.  You may specify command-line arguments to give it, as for\n\
+the \"run\" command (q.v.).");
+}
+
+
+/* Create a fundamental Ada type using default reasonable for the current
+   target machine.
+
+   Some object/debugging file formats (DWARF version 1, COFF, etc) do not
+   define fundamental types such as "int" or "double".  Others (stabs or
+   DWARF version 2, etc) do define fundamental types.  For the formats which
+   don't provide fundamental types, gdb can create such types using this
+   function.
+
+   FIXME:  Some compilers distinguish explicitly signed integral types
+   (signed short, signed int, signed long) from "regular" integral types
+   (short, int, long) in the debugging information.  There is some dis-
+   agreement as to how useful this feature is.  In particular, gcc does
+   not support this.  Also, only some debugging formats allow the
+   distinction to be passed on to a debugger.  For now, we always just
+   use "short", "int", or "long" as the type name, for both the implicit
+   and explicitly signed types.  This also makes life easier for the
+   gdb test suite since we don't have to account for the differences
+   in output depending upon what the compiler and debugging format
+   support.  We will probably have to re-examine the issue when gdb
+   starts taking it's fundamental type information directly from the
+   debugging information supplied by the compiler.  fnf@cygnus.com */
+
+static struct type *
+ada_create_fundamental_type (struct objfile *objfile, int typeid)
+{
+  struct type *type = NULL;
+
+  switch (typeid)
+    {
+    default:
+      /* FIXME:  For now, if we are asked to produce a type not in this
+         language, create the equivalent of a C integer type with the
+         name "<?type?>".  When all the dust settles from the type
+         reconstruction work, this should probably become an error. */
+      type = init_type (TYPE_CODE_INT,
+                       TARGET_INT_BIT / TARGET_CHAR_BIT,
+                       0, "<?type?>", objfile);
+      warning ("internal error: no Ada fundamental type %d", typeid);
+      break;
+    case FT_VOID:
+      type = init_type (TYPE_CODE_VOID,
+                       TARGET_CHAR_BIT / TARGET_CHAR_BIT,
+                       0, "void", objfile);
+      break;
+    case FT_CHAR:
+      type = init_type (TYPE_CODE_INT,
+                       TARGET_CHAR_BIT / TARGET_CHAR_BIT,
+                       0, "character", objfile);
+      break;
+    case FT_SIGNED_CHAR:
+      type = init_type (TYPE_CODE_INT,
+                       TARGET_CHAR_BIT / TARGET_CHAR_BIT,
+                       0, "signed char", objfile);
+      break;
+    case FT_UNSIGNED_CHAR:
+      type = init_type (TYPE_CODE_INT,
+                       TARGET_CHAR_BIT / TARGET_CHAR_BIT,
+                       TYPE_FLAG_UNSIGNED, "unsigned char", objfile);
+      break;
+    case FT_SHORT:
+      type = init_type (TYPE_CODE_INT,
+                       TARGET_SHORT_BIT / TARGET_CHAR_BIT,
+                       0, "short_integer", objfile);
+      break;
+    case FT_SIGNED_SHORT:
+      type = init_type (TYPE_CODE_INT,
+                       TARGET_SHORT_BIT / TARGET_CHAR_BIT,
+                       0, "short_integer", objfile);
+      break;
+    case FT_UNSIGNED_SHORT:
+      type = init_type (TYPE_CODE_INT,
+                       TARGET_SHORT_BIT / TARGET_CHAR_BIT,
+                       TYPE_FLAG_UNSIGNED, "unsigned short", objfile);
+      break;
+    case FT_INTEGER:
+      type = init_type (TYPE_CODE_INT,
+                       TARGET_INT_BIT / TARGET_CHAR_BIT,
+                       0, "integer", objfile);
+      break;
+    case FT_SIGNED_INTEGER:
+      type = init_type (TYPE_CODE_INT, TARGET_INT_BIT / TARGET_CHAR_BIT, 0, "integer", objfile);       /* FIXME -fnf */
+      break;
+    case FT_UNSIGNED_INTEGER:
+      type = init_type (TYPE_CODE_INT,
+                       TARGET_INT_BIT / TARGET_CHAR_BIT,
+                       TYPE_FLAG_UNSIGNED, "unsigned int", objfile);
+      break;
+    case FT_LONG:
+      type = init_type (TYPE_CODE_INT,
+                       TARGET_LONG_BIT / TARGET_CHAR_BIT,
+                       0, "long_integer", objfile);
+      break;
+    case FT_SIGNED_LONG:
+      type = init_type (TYPE_CODE_INT,
+                       TARGET_LONG_BIT / TARGET_CHAR_BIT,
+                       0, "long_integer", objfile);
+      break;
+    case FT_UNSIGNED_LONG:
+      type = init_type (TYPE_CODE_INT,
+                       TARGET_LONG_BIT / TARGET_CHAR_BIT,
+                       TYPE_FLAG_UNSIGNED, "unsigned long", objfile);
+      break;
+    case FT_LONG_LONG:
+      type = init_type (TYPE_CODE_INT,
+                       TARGET_LONG_LONG_BIT / TARGET_CHAR_BIT,
+                       0, "long_long_integer", objfile);
+      break;
+    case FT_SIGNED_LONG_LONG:
+      type = init_type (TYPE_CODE_INT,
+                       TARGET_LONG_LONG_BIT / TARGET_CHAR_BIT,
+                       0, "long_long_integer", objfile);
+      break;
+    case FT_UNSIGNED_LONG_LONG:
+      type = init_type (TYPE_CODE_INT,
+                       TARGET_LONG_LONG_BIT / TARGET_CHAR_BIT,
+                       TYPE_FLAG_UNSIGNED, "unsigned long long", objfile);
+      break;
+    case FT_FLOAT:
+      type = init_type (TYPE_CODE_FLT,
+                       TARGET_FLOAT_BIT / TARGET_CHAR_BIT,
+                       0, "float", objfile);
+      break;
+    case FT_DBL_PREC_FLOAT:
+      type = init_type (TYPE_CODE_FLT,
+                       TARGET_DOUBLE_BIT / TARGET_CHAR_BIT,
+                       0, "long_float", objfile);
+      break;
+    case FT_EXT_PREC_FLOAT:
+      type = init_type (TYPE_CODE_FLT,
+                       TARGET_LONG_DOUBLE_BIT / TARGET_CHAR_BIT,
+                       0, "long_long_float", objfile);
+      break;
+    }
+  return (type);
+}
+
+void
+ada_dump_symtab (struct symtab *s)
+{
+  int i;
+  fprintf (stderr, "New symtab: [\n");
+  fprintf (stderr, "  Name: %s/%s;\n",
+          s->dirname ? s->dirname : "?", s->filename ? s->filename : "?");
+  fprintf (stderr, "  Format: %s;\n", s->debugformat);
+  if (s->linetable != NULL)
+    {
+      fprintf (stderr, "  Line table (section %d):\n", s->block_line_section);
+      for (i = 0; i < s->linetable->nitems; i += 1)
+       {
+         struct linetable_entry *e = s->linetable->item + i;
+         fprintf (stderr, "    %4ld: %8lx\n", (long) e->line, (long) e->pc);
+       }
+    }
+  fprintf (stderr, "]\n");
+}
diff --git a/gdb/c-lang.c b/gdb/c-lang.c
new file mode 100644 (file)
index 0000000..6bbd6d9
--- /dev/null
@@ -0,0 +1,652 @@
+/* C language support routines for GDB, the GNU debugger.
+   Copyright 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2002
+   Free Software Foundation, Inc.
+
+   This file is part of GDB.
+
+   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.  */
+
+#include "defs.h"
+#include "symtab.h"
+#include "gdbtypes.h"
+#include "expression.h"
+#include "parser-defs.h"
+#include "language.h"
+#include "c-lang.h"
+#include "valprint.h"
+#include "macroscope.h"
+#include "gdb_assert.h"
+#include "charset.h"
+
+extern void _initialize_c_language (void);
+static void c_emit_char (int c, struct ui_file * stream, int quoter);
+
+/* Print the character C on STREAM as part of the contents of a literal
+   string whose delimiter is QUOTER.  Note that that format for printing
+   characters and strings is language specific. */
+
+static void
+c_emit_char (register int c, struct ui_file *stream, int quoter)
+{
+  const char *escape;
+  int host_char;
+
+  c &= 0xFF;                   /* Avoid sign bit follies */
+
+  escape = c_target_char_has_backslash_escape (c);
+  if (escape)
+    {
+      if (quoter == '"' && strcmp (escape, "0") == 0)
+       /* Print nulls embedded in double quoted strings as \000 to
+          prevent ambiguity.  */
+       fprintf_filtered (stream, "\\000");
+      else
+       fprintf_filtered (stream, "\\%s", escape);
+    }
+  else if (target_char_to_host (c, &host_char)
+           && host_char_print_literally (host_char))
+    {
+      if (host_char == '\\' || host_char == quoter)
+        fputs_filtered ("\\", stream);
+      fprintf_filtered (stream, "%c", host_char);
+    }
+  else
+    fprintf_filtered (stream, "\\%.3o", (unsigned int) c);
+}
+
+void
+c_printchar (int c, struct ui_file *stream)
+{
+  fputc_filtered ('\'', stream);
+  LA_EMIT_CHAR (c, stream, '\'');
+  fputc_filtered ('\'', stream);
+}
+
+/* Print the character string STRING, printing at most LENGTH characters.
+   LENGTH is -1 if the string is nul terminated.  Each character is WIDTH bytes
+   long.  Printing stops early if the number hits print_max; repeat counts are
+   printed as appropriate.  Print ellipses at the end if we had to stop before
+   printing LENGTH characters, or if FORCE_ELLIPSES.  */
+
+void
+c_printstr (struct ui_file *stream, char *string, unsigned int length,
+           int width, int force_ellipses)
+{
+  register unsigned int i;
+  unsigned int things_printed = 0;
+  int in_quotes = 0;
+  int need_comma = 0;
+  extern int inspect_it;
+
+  /* If the string was not truncated due to `set print elements', and
+     the last byte of it is a null, we don't print that, in traditional C
+     style.  */
+  if (!force_ellipses
+      && length > 0
+      && (extract_unsigned_integer (string + (length - 1) * width, width)
+          == '\0'))
+    length--;
+
+  if (length == 0)
+    {
+      fputs_filtered ("\"\"", stream);
+      return;
+    }
+
+  for (i = 0; i < length && things_printed < print_max; ++i)
+    {
+      /* Position of the character we are examining
+         to see whether it is repeated.  */
+      unsigned int rep1;
+      /* Number of repetitions we have detected so far.  */
+      unsigned int reps;
+      unsigned long current_char;
+
+      QUIT;
+
+      if (need_comma)
+       {
+         fputs_filtered (", ", stream);
+         need_comma = 0;
+       }
+
+      current_char = extract_unsigned_integer (string + i * width, width);
+
+      rep1 = i + 1;
+      reps = 1;
+      while (rep1 < length
+            && extract_unsigned_integer (string + rep1 * width, width)
+            == current_char)
+       {
+         ++rep1;
+         ++reps;
+       }
+
+      if (reps > repeat_count_threshold)
+       {
+         if (in_quotes)
+           {
+             if (inspect_it)
+               fputs_filtered ("\\\", ", stream);
+             else
+               fputs_filtered ("\", ", stream);
+             in_quotes = 0;
+           }
+         LA_PRINT_CHAR (current_char, stream);
+         fprintf_filtered (stream, " <repeats %u times>", reps);
+         i = rep1 - 1;
+         things_printed += repeat_count_threshold;
+         need_comma = 1;
+       }
+      else
+       {
+         if (!in_quotes)
+           {
+             if (inspect_it)
+               fputs_filtered ("\\\"", stream);
+             else
+               fputs_filtered ("\"", stream);
+             in_quotes = 1;
+           }
+         LA_EMIT_CHAR (current_char, stream, '"');
+         ++things_printed;
+       }
+    }
+
+  /* Terminate the quotes if necessary.  */
+  if (in_quotes)
+    {
+      if (inspect_it)
+       fputs_filtered ("\\\"", stream);
+      else
+       fputs_filtered ("\"", stream);
+    }
+
+  if (force_ellipses || i < length)
+    fputs_filtered ("...", stream);
+}
+
+/* Create a fundamental C type using default reasonable for the current
+   target machine.
+
+   Some object/debugging file formats (DWARF version 1, COFF, etc) do not
+   define fundamental types such as "int" or "double".  Others (stabs or
+   DWARF version 2, etc) do define fundamental types.  For the formats which
+   don't provide fundamental types, gdb can create such types using this
+   function.
+
+   FIXME:  Some compilers distinguish explicitly signed integral types
+   (signed short, signed int, signed long) from "regular" integral types
+   (short, int, long) in the debugging information.  There is some dis-
+   agreement as to how useful this feature is.  In particular, gcc does
+   not support this.  Also, only some debugging formats allow the
+   distinction to be passed on to a debugger.  For now, we always just
+   use "short", "int", or "long" as the type name, for both the implicit
+   and explicitly signed types.  This also makes life easier for the
+   gdb test suite since we don't have to account for the differences
+   in output depending upon what the compiler and debugging format
+   support.  We will probably have to re-examine the issue when gdb
+   starts taking it's fundamental type information directly from the
+   debugging information supplied by the compiler.  fnf@cygnus.com */
+
+struct type *
+c_create_fundamental_type (struct objfile *objfile, int typeid)
+{
+  register struct type *type = NULL;
+
+  switch (typeid)
+    {
+    default:
+      /* FIXME:  For now, if we are asked to produce a type not in this
+         language, create the equivalent of a C integer type with the
+         name "<?type?>".  When all the dust settles from the type
+         reconstruction work, this should probably become an error. */
+      type = init_type (TYPE_CODE_INT,
+                       TARGET_INT_BIT / TARGET_CHAR_BIT,
+                       0, "<?type?>", objfile);
+      warning ("internal error: no C/C++ fundamental type %d", typeid);
+      break;
+    case FT_VOID:
+      type = init_type (TYPE_CODE_VOID,
+                       TARGET_CHAR_BIT / TARGET_CHAR_BIT,
+                       0, "void", objfile);
+      break;
+    case FT_BOOLEAN:
+      type = init_type (TYPE_CODE_BOOL,
+                       TARGET_CHAR_BIT / TARGET_CHAR_BIT,
+                       0, "bool", objfile);
+      break;
+    case FT_CHAR:
+      type = init_type (TYPE_CODE_INT,
+                       TARGET_CHAR_BIT / TARGET_CHAR_BIT,
+                       TYPE_FLAG_NOSIGN, "char", objfile);
+      break;
+    case FT_SIGNED_CHAR:
+      type = init_type (TYPE_CODE_INT,
+                       TARGET_CHAR_BIT / TARGET_CHAR_BIT,
+                       0, "signed char", objfile);
+      break;
+    case FT_UNSIGNED_CHAR:
+      type = init_type (TYPE_CODE_INT,
+                       TARGET_CHAR_BIT / TARGET_CHAR_BIT,
+                       TYPE_FLAG_UNSIGNED, "unsigned char", objfile);
+      break;
+    case FT_SHORT:
+      type = init_type (TYPE_CODE_INT,
+                       TARGET_SHORT_BIT / TARGET_CHAR_BIT,
+                       0, "short", objfile);
+      break;
+    case FT_SIGNED_SHORT:
+      type = init_type (TYPE_CODE_INT,
+                       TARGET_SHORT_BIT / TARGET_CHAR_BIT,
+                       0, "short", objfile);   /* FIXME-fnf */
+      break;
+    case FT_UNSIGNED_SHORT:
+      type = init_type (TYPE_CODE_INT,
+                       TARGET_SHORT_BIT / TARGET_CHAR_BIT,
+                       TYPE_FLAG_UNSIGNED, "unsigned short", objfile);
+      break;
+    case FT_INTEGER:
+      type = init_type (TYPE_CODE_INT,
+                       TARGET_INT_BIT / TARGET_CHAR_BIT,
+                       0, "int", objfile);
+      break;
+    case FT_SIGNED_INTEGER:
+      type = init_type (TYPE_CODE_INT,
+                       TARGET_INT_BIT / TARGET_CHAR_BIT,
+                       0, "int", objfile);     /* FIXME -fnf */
+      break;
+    case FT_UNSIGNED_INTEGER:
+      type = init_type (TYPE_CODE_INT,
+                       TARGET_INT_BIT / TARGET_CHAR_BIT,
+                       TYPE_FLAG_UNSIGNED, "unsigned int", objfile);
+      break;
+    case FT_LONG:
+      type = init_type (TYPE_CODE_INT,
+                       TARGET_LONG_BIT / TARGET_CHAR_BIT,
+                       0, "long", objfile);
+      break;
+    case FT_SIGNED_LONG:
+      type = init_type (TYPE_CODE_INT,
+                       TARGET_LONG_BIT / TARGET_CHAR_BIT,
+                       0, "long", objfile);    /* FIXME -fnf */
+      break;
+    case FT_UNSIGNED_LONG:
+      type = init_type (TYPE_CODE_INT,
+                       TARGET_LONG_BIT / TARGET_CHAR_BIT,
+                       TYPE_FLAG_UNSIGNED, "unsigned long", objfile);
+      break;
+    case FT_LONG_LONG:
+      type = init_type (TYPE_CODE_INT,
+                       TARGET_LONG_LONG_BIT / TARGET_CHAR_BIT,
+                       0, "long long", objfile);
+      break;
+    case FT_SIGNED_LONG_LONG:
+      type = init_type (TYPE_CODE_INT,
+                       TARGET_LONG_LONG_BIT / TARGET_CHAR_BIT,
+                       0, "signed long long", objfile);
+      break;
+    case FT_UNSIGNED_LONG_LONG:
+      type = init_type (TYPE_CODE_INT,
+                       TARGET_LONG_LONG_BIT / TARGET_CHAR_BIT,
+                       TYPE_FLAG_UNSIGNED, "unsigned long long", objfile);
+      break;
+    case FT_FLOAT:
+      type = init_type (TYPE_CODE_FLT,
+                       TARGET_FLOAT_BIT / TARGET_CHAR_BIT,
+                       0, "float", objfile);
+      break;
+    case FT_DBL_PREC_FLOAT:
+      type = init_type (TYPE_CODE_FLT,
+                       TARGET_DOUBLE_BIT / TARGET_CHAR_BIT,
+                       0, "double", objfile);
+      break;
+    case FT_EXT_PREC_FLOAT:
+      type = init_type (TYPE_CODE_FLT,
+                       TARGET_LONG_DOUBLE_BIT / TARGET_CHAR_BIT,
+                       0, "long double", objfile);
+      break;
+    case FT_COMPLEX:
+      type = init_type (TYPE_CODE_FLT,
+                       2 * TARGET_FLOAT_BIT / TARGET_CHAR_BIT,
+                       0, "complex float", objfile);
+      TYPE_TARGET_TYPE (type)
+       = init_type (TYPE_CODE_FLT, TARGET_FLOAT_BIT / TARGET_CHAR_BIT,
+                    0, "float", objfile);
+      break;
+    case FT_DBL_PREC_COMPLEX:
+      type = init_type (TYPE_CODE_FLT,
+                       2 * TARGET_DOUBLE_BIT / TARGET_CHAR_BIT,
+                       0, "complex double", objfile);
+      TYPE_TARGET_TYPE (type)
+       = init_type (TYPE_CODE_FLT, TARGET_DOUBLE_BIT / TARGET_CHAR_BIT,
+                    0, "double", objfile);
+      break;
+    case FT_EXT_PREC_COMPLEX:
+      type = init_type (TYPE_CODE_FLT,
+                       2 * TARGET_LONG_DOUBLE_BIT / TARGET_CHAR_BIT,
+                       0, "complex long double", objfile);
+      TYPE_TARGET_TYPE (type)
+       = init_type (TYPE_CODE_FLT, TARGET_LONG_DOUBLE_BIT / TARGET_CHAR_BIT,
+                    0, "long double", objfile);
+      break;
+    case FT_TEMPLATE_ARG:
+      type = init_type (TYPE_CODE_TEMPLATE_ARG,
+                       0,
+                       0, "<template arg>", objfile);
+      break;
+    }
+  return (type);
+}
+\f
+/* Preprocessing and parsing C and C++ expressions.  */
+
+
+/* When we find that lexptr (the global var defined in parse.c) is
+   pointing at a macro invocation, we expand the invocation, and call
+   scan_macro_expansion to save the old lexptr here and point lexptr
+   into the expanded text.  When we reach the end of that, we call
+   end_macro_expansion to pop back to the value we saved here.  The
+   macro expansion code promises to return only fully-expanded text,
+   so we don't need to "push" more than one level.
+
+   This is disgusting, of course.  It would be cleaner to do all macro
+   expansion beforehand, and then hand that to lexptr.  But we don't
+   really know where the expression ends.  Remember, in a command like
+
+     (gdb) break *ADDRESS if CONDITION
+
+   we evaluate ADDRESS in the scope of the current frame, but we
+   evaluate CONDITION in the scope of the breakpoint's location.  So
+   it's simply wrong to try to macro-expand the whole thing at once.  */
+static char *macro_original_text;
+static char *macro_expanded_text;
+
+
+void
+scan_macro_expansion (char *expansion)
+{
+  /* We'd better not be trying to push the stack twice.  */
+  gdb_assert (! macro_original_text);
+  gdb_assert (! macro_expanded_text);
+
+  /* Save the old lexptr value, so we can return to it when we're done
+     parsing the expanded text.  */
+  macro_original_text = lexptr;
+  lexptr = expansion;
+
+  /* Save the expanded text, so we can free it when we're finished.  */
+  macro_expanded_text = expansion;
+}
+
+
+int
+scanning_macro_expansion (void)
+{
+  return macro_original_text != 0;
+}
+
+
+void 
+finished_macro_expansion (void)
+{
+  /* There'd better be something to pop back to, and we better have
+     saved a pointer to the start of the expanded text.  */
+  gdb_assert (macro_original_text);
+  gdb_assert (macro_expanded_text);
+
+  /* Pop back to the original text.  */
+  lexptr = macro_original_text;
+  macro_original_text = 0;
+
+  /* Free the expanded text.  */
+  xfree (macro_expanded_text);
+  macro_expanded_text = 0;
+}
+
+
+static void
+scan_macro_cleanup (void *dummy)
+{
+  if (macro_original_text)
+    finished_macro_expansion ();
+}
+
+
+/* We set these global variables before calling c_parse, to tell it
+   how it to find macro definitions for the expression at hand.  */
+macro_lookup_ftype *expression_macro_lookup_func;
+void *expression_macro_lookup_baton;
+
+
+static struct macro_definition *
+null_macro_lookup (const char *name, void *baton)
+{
+  return 0;
+}
+
+
+static int
+c_preprocess_and_parse (void)
+{
+  /* Set up a lookup function for the macro expander.  */
+  struct macro_scope *scope = 0;
+  struct cleanup *back_to = make_cleanup (free_current_contents, &scope);
+
+  if (expression_context_block)
+    scope = sal_macro_scope (find_pc_line (expression_context_pc, 0));
+  else
+    scope = default_macro_scope ();
+
+  if (scope)
+    {
+      expression_macro_lookup_func = standard_macro_lookup;
+      expression_macro_lookup_baton = (void *) scope;
+    }
+  else
+    {
+      expression_macro_lookup_func = null_macro_lookup;
+      expression_macro_lookup_baton = 0;      
+    }
+
+  gdb_assert (! macro_original_text);
+  make_cleanup (scan_macro_cleanup, 0);
+
+  {
+    int result = c_parse ();
+    do_cleanups (back_to);
+    return result;
+  }
+}
+
+
+\f
+/* Table mapping opcodes into strings for printing operators
+   and precedences of the operators.  */
+
+const struct op_print c_op_print_tab[] =
+{
+  {",", BINOP_COMMA, PREC_COMMA, 0},
+  {"=", BINOP_ASSIGN, PREC_ASSIGN, 1},
+  {"||", BINOP_LOGICAL_OR, PREC_LOGICAL_OR, 0},
+  {"&&", BINOP_LOGICAL_AND, PREC_LOGICAL_AND, 0},
+  {"|", BINOP_BITWISE_IOR, PREC_BITWISE_IOR, 0},
+  {"^", BINOP_BITWISE_XOR, PREC_BITWISE_XOR, 0},
+  {"&", BINOP_BITWISE_AND, PREC_BITWISE_AND, 0},
+  {"==", BINOP_EQUAL, PREC_EQUAL, 0},
+  {"!=", BINOP_NOTEQUAL, PREC_EQUAL, 0},
+  {"<=", BINOP_LEQ, PREC_ORDER, 0},
+  {">=", BINOP_GEQ, PREC_ORDER, 0},
+  {">", BINOP_GTR, PREC_ORDER, 0},
+  {"<", BINOP_LESS, PREC_ORDER, 0},
+  {">>", BINOP_RSH, PREC_SHIFT, 0},
+  {"<<", BINOP_LSH, PREC_SHIFT, 0},
+  {"+", BINOP_ADD, PREC_ADD, 0},
+  {"-", BINOP_SUB, PREC_ADD, 0},
+  {"*", BINOP_MUL, PREC_MUL, 0},
+  {"/", BINOP_DIV, PREC_MUL, 0},
+  {"%", BINOP_REM, PREC_MUL, 0},
+  {"@", BINOP_REPEAT, PREC_REPEAT, 0},
+  {"-", UNOP_NEG, PREC_PREFIX, 0},
+  {"!", UNOP_LOGICAL_NOT, PREC_PREFIX, 0},
+  {"~", UNOP_COMPLEMENT, PREC_PREFIX, 0},
+  {"*", UNOP_IND, PREC_PREFIX, 0},
+  {"&", UNOP_ADDR, PREC_PREFIX, 0},
+  {"sizeof ", UNOP_SIZEOF, PREC_PREFIX, 0},
+  {"++", UNOP_PREINCREMENT, PREC_PREFIX, 0},
+  {"--", UNOP_PREDECREMENT, PREC_PREFIX, 0},
+  {NULL, 0, 0, 0}
+};
+\f
+struct type **const (c_builtin_types[]) =
+{
+  &builtin_type_int,
+  &builtin_type_long,
+  &builtin_type_short,
+  &builtin_type_char,
+  &builtin_type_float,
+  &builtin_type_double,
+  &builtin_type_void,
+  &builtin_type_long_long,
+  &builtin_type_signed_char,
+  &builtin_type_unsigned_char,
+  &builtin_type_unsigned_short,
+  &builtin_type_unsigned_int,
+  &builtin_type_unsigned_long,
+  &builtin_type_unsigned_long_long,
+  &builtin_type_long_double,
+  &builtin_type_complex,
+  &builtin_type_double_complex,
+  0
+};
+
+const struct language_defn c_language_defn =
+{
+  "c",                         /* Language name */
+  language_c,
+  c_builtin_types,
+  range_check_off,
+  type_check_off,
+  case_sensitive_on,
+  c_preprocess_and_parse,
+  c_error,
+  evaluate_subexp_standard,
+  c_printchar,                 /* Print a character constant */
+  c_printstr,                  /* Function to print string constant */
+  c_emit_char,                 /* Print a single char */
+  c_create_fundamental_type,   /* Create fundamental type in this language */
+  c_print_type,                        /* Print a type using appropriate syntax */
+  c_val_print,                 /* Print a value using appropriate syntax */
+  c_value_print,               /* Print a top-level value */
+  {"", "", "", ""},            /* Binary format info */
+  {"0%lo", "0", "o", ""},      /* Octal format info */
+  {"%ld", "", "d", ""},                /* Decimal format info */
+  {"0x%lx", "0x", "x", ""},    /* Hex format info */
+  c_op_print_tab,              /* expression operators for printing */
+  1,                           /* c-style arrays */
+  0,                           /* String lower bound */
+  &builtin_type_char,          /* Type of string elements */
+  LANG_MAGIC
+};
+
+struct type **const (cplus_builtin_types[]) =
+{
+  &builtin_type_int,
+  &builtin_type_long,
+  &builtin_type_short,
+  &builtin_type_char,
+  &builtin_type_float,
+  &builtin_type_double,
+  &builtin_type_void,
+  &builtin_type_long_long,
+  &builtin_type_signed_char,
+  &builtin_type_unsigned_char,
+  &builtin_type_unsigned_short,
+  &builtin_type_unsigned_int,
+  &builtin_type_unsigned_long,
+  &builtin_type_unsigned_long_long,
+  &builtin_type_long_double,
+  &builtin_type_complex,
+  &builtin_type_double_complex,
+  &builtin_type_bool,
+  0
+};
+
+const struct language_defn cplus_language_defn =
+{
+  "c++",                       /* Language name */
+  language_cplus,
+  cplus_builtin_types,
+  range_check_off,
+  type_check_off,
+  case_sensitive_on,
+  c_preprocess_and_parse,
+  c_error,
+  evaluate_subexp_standard,
+  c_printchar,                 /* Print a character constant */
+  c_printstr,                  /* Function to print string constant */
+  c_emit_char,                 /* Print a single char */
+  c_create_fundamental_type,   /* Create fundamental type in this language */
+  c_print_type,                        /* Print a type using appropriate syntax */
+  c_val_print,                 /* Print a value using appropriate syntax */
+  c_value_print,               /* Print a top-level value */
+  {"", "", "", ""},            /* Binary format info */
+  {"0%lo", "0", "o", ""},      /* Octal format info */
+  {"%ld", "", "d", ""},                /* Decimal format info */
+  {"0x%lx", "0x", "x", ""},    /* Hex format info */
+  c_op_print_tab,              /* expression operators for printing */
+  1,                           /* c-style arrays */
+  0,                           /* String lower bound */
+  &builtin_type_char,          /* Type of string elements */
+  LANG_MAGIC
+};
+
+const struct language_defn asm_language_defn =
+{
+  "asm",                       /* Language name */
+  language_asm,
+  c_builtin_types,
+  range_check_off,
+  type_check_off,
+  case_sensitive_on,
+  c_preprocess_and_parse,
+  c_error,
+  evaluate_subexp_standard,
+  c_printchar,                 /* Print a character constant */
+  c_printstr,                  /* Function to print string constant */
+  c_emit_char,                 /* Print a single char */
+  c_create_fundamental_type,   /* Create fundamental type in this language */
+  c_print_type,                        /* Print a type using appropriate syntax */
+  c_val_print,                 /* Print a value using appropriate syntax */
+  c_value_print,               /* Print a top-level value */
+  {"", "", "", ""},            /* Binary format info */
+  {"0%lo", "0", "o", ""},      /* Octal format info */
+  {"%ld", "", "d", ""},                /* Decimal format info */
+  {"0x%lx", "0x", "x", ""},    /* Hex format info */
+  c_op_print_tab,              /* expression operators for printing */
+  1,                           /* c-style arrays */
+  0,                           /* String lower bound */
+  &builtin_type_char,          /* Type of string elements */
+  LANG_MAGIC
+};
+
+void
+_initialize_c_language (void)
+{
+  add_language (&c_language_defn);
+  add_language (&cplus_language_defn);
+  add_language (&asm_language_defn);
+}
diff --git a/gdb/coffread.c b/gdb/coffread.c
new file mode 100644 (file)
index 0000000..d794a7d
--- /dev/null
@@ -0,0 +1,2166 @@
+/* Read coff symbol tables and convert to internal format, for GDB.
+   Copyright 1987, 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1995, 1996,
+   1997, 1998, 1999, 2000, 2001, 2002
+   Free Software Foundation, Inc.
+   Contributed by David D. Johnson, Brown University (ddj@cs.brown.edu).
+
+   This file is part of GDB.
+
+   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.  */
+
+#include "defs.h"
+#include "symtab.h"
+#include "gdbtypes.h"
+#include "demangle.h"
+#include "breakpoint.h"
+
+#include "bfd.h"
+#include "gdb_obstack.h"
+
+#include "gdb_string.h"
+#include <ctype.h>
+
+#include "coff/internal.h"     /* Internal format of COFF symbols in BFD */
+#include "libcoff.h"           /* FIXME secret internal data from BFD */
+
+#include "symfile.h"
+#include "objfiles.h"
+#include "buildsym.h"
+#include "gdb-stabs.h"
+#include "stabsread.h"
+#include "complaints.h"
+#include "target.h"
+#include "gdb_assert.h"
+
+extern void _initialize_coffread (void);
+
+struct coff_symfile_info
+  {
+    file_ptr min_lineno_offset;        /* Where in file lowest line#s are */
+    file_ptr max_lineno_offset;        /* 1+last byte of line#s in file */
+
+    CORE_ADDR textaddr;                /* Addr of .text section. */
+    unsigned int textsize;     /* Size of .text section. */
+    struct stab_section_list *stabsects;       /* .stab sections.  */
+    asection *stabstrsect;     /* Section pointer for .stab section */
+    char *stabstrdata;
+  };
+
+/* Translate an external name string into a user-visible name.  */
+#define        EXTERNAL_NAME(string, abfd) \
+       (string[0] == bfd_get_symbol_leading_char(abfd)? string+1: string)
+
+/* To be an sdb debug type, type must have at least a basic or primary
+   derived type.  Using this rather than checking against T_NULL is
+   said to prevent core dumps if we try to operate on Michael Bloom
+   dbx-in-coff file.  */
+
+#define SDB_TYPE(type) (BTYPE(type) | (type & N_TMASK))
+
+/* Core address of start and end of text of current source file.
+   This comes from a ".text" symbol where x_nlinno > 0.  */
+
+static CORE_ADDR current_source_start_addr;
+static CORE_ADDR current_source_end_addr;
+
+/* The addresses of the symbol table stream and number of symbols
+   of the object file we are reading (as copied into core).  */
+
+static bfd *nlist_bfd_global;
+static int nlist_nsyms_global;
+
+
+/* Pointers to scratch storage, used for reading raw symbols and auxents.  */
+
+static char *temp_sym;
+static char *temp_aux;
+
+/* Local variables that hold the shift and mask values for the
+   COFF file that we are currently reading.  These come back to us
+   from BFD, and are referenced by their macro names, as well as
+   internally to the BTYPE, ISPTR, ISFCN, ISARY, ISTAG, and DECREF
+   macros from include/coff/internal.h .  */
+
+static unsigned local_n_btmask;
+static unsigned local_n_btshft;
+static unsigned local_n_tmask;
+static unsigned local_n_tshift;
+
+#define        N_BTMASK        local_n_btmask
+#define        N_BTSHFT        local_n_btshft
+#define        N_TMASK         local_n_tmask
+#define        N_TSHIFT        local_n_tshift
+
+/* Local variables that hold the sizes in the file of various COFF structures.
+   (We only need to know this to read them from the file -- BFD will then
+   translate the data in them, into `internal_xxx' structs in the right
+   byte order, alignment, etc.)  */
+
+static unsigned local_linesz;
+static unsigned local_symesz;
+static unsigned local_auxesz;
+
+/* This is set if this is a PE format file.  */
+
+static int pe_file;
+
+/* Chain of typedefs of pointers to empty struct/union types.
+   They are chained thru the SYMBOL_VALUE_CHAIN.  */
+
+static struct symbol *opaque_type_chain[HASHSIZE];
+
+/* Complaints about various problems in the file being read  */
+
+struct complaint ef_complaint =
+{"Unmatched .ef symbol(s) ignored starting at symnum %d", 0, 0};
+
+struct complaint ef_stack_complaint =
+{"`.ef' symbol without matching `.bf' symbol ignored starting at symnum %d", 0, 0};
+
+struct complaint eb_stack_complaint =
+{"`.eb' symbol without matching `.bb' symbol ignored starting at symnum %d", 0, 0};
+
+struct complaint bf_no_aux_complaint =
+{"`.bf' symbol %d has no aux entry", 0, 0};
+
+struct complaint ef_no_aux_complaint =
+{"`.ef' symbol %d has no aux entry", 0, 0};
+
+struct complaint lineno_complaint =
+{"Line number pointer %d lower than start of line numbers", 0, 0};
+
+struct complaint unexpected_type_complaint =
+{"Unexpected type for symbol %s", 0, 0};
+
+struct complaint bad_sclass_complaint =
+{"Bad n_sclass for symbol %s", 0, 0};
+
+struct complaint misordered_blocks_complaint =
+{"Blocks out of order at address %x", 0, 0};
+
+struct complaint tagndx_bad_complaint =
+{"Symbol table entry for %s has bad tagndx value", 0, 0};
+
+struct complaint eb_complaint =
+{"Mismatched .eb symbol ignored starting at symnum %d", 0, 0};
+
+/* Simplified internal version of coff symbol table information */
+
+struct coff_symbol
+  {
+    char *c_name;
+    int c_symnum;              /* symbol number of this entry */
+    int c_naux;                        /* 0 if syment only, 1 if syment + auxent, etc */
+    long c_value;
+    int c_sclass;
+    int c_secnum;
+    unsigned int c_type;
+  };
+
+extern void stabsread_clear_cache (void);
+
+static struct type *coff_read_struct_type (int, int, int);
+
+static struct type *decode_base_type (struct coff_symbol *,
+                                     unsigned int, union internal_auxent *);
+
+static struct type *decode_type (struct coff_symbol *, unsigned int,
+                                union internal_auxent *);
+
+static struct type *decode_function_type (struct coff_symbol *,
+                                         unsigned int,
+                                         union internal_auxent *);
+
+static struct type *coff_read_enum_type (int, int, int);
+
+static struct symbol *process_coff_symbol (struct coff_symbol *,
+                                          union internal_auxent *,
+                                          struct objfile *);
+
+static void patch_opaque_types (struct symtab *);
+
+static void enter_linenos (long, int, int, struct objfile *);
+
+static void free_linetab (void);
+
+static void free_linetab_cleanup (void *ignore);
+
+static int init_lineno (bfd *, long, int);
+
+static char *getsymname (struct internal_syment *);
+
+static char *coff_getfilename (union internal_auxent *);
+
+static void free_stringtab (void);
+
+static void free_stringtab_cleanup (void *ignore);
+
+static int init_stringtab (bfd *, long);
+
+static void read_one_sym (struct coff_symbol *,
+                         struct internal_syment *, union internal_auxent *);
+
+static void coff_symtab_read (long, unsigned int, struct objfile *);
+\f
+/* We are called once per section from coff_symfile_read.  We
+   need to examine each section we are passed, check to see
+   if it is something we are interested in processing, and
+   if so, stash away some access information for the section.
+
+   FIXME: The section names should not be hardwired strings (what
+   should they be?  I don't think most object file formats have enough
+   section flags to specify what kind of debug section it is
+   -kingdon).  */
+
+static void
+coff_locate_sections (bfd *abfd, asection *sectp, void *csip)
+{
+  register struct coff_symfile_info *csi;
+  const char *name;
+
+  csi = (struct coff_symfile_info *) csip;
+  name = bfd_get_section_name (abfd, sectp);
+  if (STREQ (name, ".text"))
+    {
+      csi->textaddr = bfd_section_vma (abfd, sectp);
+      csi->textsize += bfd_section_size (abfd, sectp);
+    }
+  else if (strncmp (name, ".text", sizeof ".text" - 1) == 0)
+    {
+      csi->textsize += bfd_section_size (abfd, sectp);
+    }
+  else if (STREQ (name, ".stabstr"))
+    {
+      csi->stabstrsect = sectp;
+    }
+  else if (strncmp (name, ".stab", sizeof ".stab" - 1) == 0)
+    {
+      const char *s;
+
+      /* We can have multiple .stab sections if linked with
+         --split-by-reloc.  */
+      for (s = name + sizeof ".stab" - 1; *s != '\0'; s++)
+       if (!isdigit (*s))
+         break;
+      if (*s == '\0')
+       {
+         struct stab_section_list *n, **pn;
+
+         n = ((struct stab_section_list *)
+              xmalloc (sizeof (struct stab_section_list)));
+         n->section = sectp;
+         n->next = NULL;
+         for (pn = &csi->stabsects; *pn != NULL; pn = &(*pn)->next)
+           ;
+         *pn = n;
+
+         /* This will be run after coffstab_build_psymtabs is called
+            in coff_symfile_read, at which point we no longer need
+            the information.  */
+         make_cleanup (xfree, n);
+       }
+    }
+}
+
+/* Return the section_offsets* that CS points to.  */
+static int cs_to_section (struct coff_symbol *, struct objfile *);
+
+struct find_targ_sec_arg
+  {
+    int targ_index;
+    asection **resultp;
+  };
+
+static void
+find_targ_sec (bfd *abfd, asection *sect, void *obj)
+{
+  struct find_targ_sec_arg *args = (struct find_targ_sec_arg *) obj;
+  if (sect->target_index == args->targ_index)
+    *args->resultp = sect;
+}
+
+/* Return the section number (SECT_OFF_*) that CS points to.  */
+static int
+cs_to_section (struct coff_symbol *cs, struct objfile *objfile)
+{
+  asection *sect = NULL;
+  struct find_targ_sec_arg args;
+  int off = SECT_OFF_TEXT (objfile);
+
+  args.targ_index = cs->c_secnum;
+  args.resultp = &sect;
+  bfd_map_over_sections (objfile->obfd, find_targ_sec, &args);
+  if (sect != NULL)
+    {
+      /* This is the section.  Figure out what SECT_OFF_* code it is.  */
+      if (bfd_get_section_flags (abfd, sect) & SEC_CODE)
+       off = SECT_OFF_TEXT (objfile);
+      else if (bfd_get_section_flags (abfd, sect) & SEC_LOAD)
+       off = SECT_OFF_DATA (objfile);
+      else
+       /* Just return the bfd section index. */
+       off = sect->index;
+    }
+  return off;
+}
+
+/* Return the address of the section of a COFF symbol.  */
+
+static CORE_ADDR cs_section_address (struct coff_symbol *, bfd *);
+
+static CORE_ADDR
+cs_section_address (struct coff_symbol *cs, bfd *abfd)
+{
+  asection *sect = NULL;
+  struct find_targ_sec_arg args;
+  CORE_ADDR addr = 0;
+
+  args.targ_index = cs->c_secnum;
+  args.resultp = &sect;
+  bfd_map_over_sections (abfd, find_targ_sec, &args);
+  if (sect != NULL)
+    addr = bfd_get_section_vma (objfile->obfd, sect);
+  return addr;
+}
+
+/* Look up a coff type-number index.  Return the address of the slot
+   where the type for that index is stored.
+   The type-number is in INDEX. 
+
+   This can be used for finding the type associated with that index
+   or for associating a new type with the index.  */
+
+static struct type **
+coff_lookup_type (register int index)
+{
+  if (index >= type_vector_length)
+    {
+      int old_vector_length = type_vector_length;
+
+      type_vector_length *= 2;
+      if (index /* is still */  >= type_vector_length)
+       type_vector_length = index * 2;
+
+      type_vector = (struct type **)
+       xrealloc ((char *) type_vector,
+                 type_vector_length * sizeof (struct type *));
+      memset (&type_vector[old_vector_length], 0,
+        (type_vector_length - old_vector_length) * sizeof (struct type *));
+    }
+  return &type_vector[index];
+}
+
+/* Make sure there is a type allocated for type number index
+   and return the type object.
+   This can create an empty (zeroed) type object.  */
+
+static struct type *
+coff_alloc_type (int index)
+{
+  register struct type **type_addr = coff_lookup_type (index);
+  register struct type *type = *type_addr;
+
+  /* If we are referring to a type not known at all yet,
+     allocate an empty type for it.
+     We will fill it in later if we find out how.  */
+  if (type == NULL)
+    {
+      type = alloc_type (current_objfile);
+      *type_addr = type;
+    }
+  return type;
+}
+\f
+/* Start a new symtab for a new source file.
+   This is called when a COFF ".file" symbol is seen;
+   it indicates the start of data for one original source file.  */
+
+static void
+coff_start_symtab (char *name)
+{
+  start_symtab (
+  /* We fill in the filename later.  start_symtab puts
+     this pointer into last_source_file and we put it in
+     subfiles->name, which end_symtab frees; that's why
+     it must be malloc'd.  */
+                savestring (name, strlen (name)),
+  /* We never know the directory name for COFF.  */
+                NULL,
+  /* The start address is irrelevant, since we set
+     last_source_start_addr in coff_end_symtab.  */
+                0);
+  record_debugformat ("COFF");
+}
+
+/* Save the vital information from when starting to read a file,
+   for use when closing off the current file.
+   NAME is the file name the symbols came from, START_ADDR is the first
+   text address for the file, and SIZE is the number of bytes of text.  */
+
+static void
+complete_symtab (char *name, CORE_ADDR start_addr, unsigned int size)
+{
+  if (last_source_file != NULL)
+    xfree (last_source_file);
+  last_source_file = savestring (name, strlen (name));
+  current_source_start_addr = start_addr;
+  current_source_end_addr = start_addr + size;
+
+  if (current_objfile->ei.entry_point >= current_source_start_addr &&
+      current_objfile->ei.entry_point < current_source_end_addr)
+    {
+      current_objfile->ei.entry_file_lowpc = current_source_start_addr;
+      current_objfile->ei.entry_file_highpc = current_source_end_addr;
+    }
+}
+
+/* Finish the symbol definitions for one main source file,
+   close off all the lexical contexts for that file
+   (creating struct block's for them), then make the
+   struct symtab for that file and put it in the list of all such. */
+
+static void
+coff_end_symtab (struct objfile *objfile)
+{
+  struct symtab *symtab;
+
+  last_source_start_addr = current_source_start_addr;
+
+  symtab = end_symtab (current_source_end_addr, objfile, SECT_OFF_TEXT (objfile));
+
+  if (symtab != NULL)
+    free_named_symtabs (symtab->filename);
+
+  /* Reinitialize for beginning of new file. */
+  last_source_file = NULL;
+}
+\f
+static void
+record_minimal_symbol (char *name, CORE_ADDR address,
+                      enum minimal_symbol_type type, struct objfile *objfile)
+{
+  /* We don't want TDESC entry points in the minimal symbol table */
+  if (name[0] == '@')
+    return;
+
+  prim_record_minimal_symbol (name, address, type, objfile);
+}
+\f
+/* coff_symfile_init ()
+   is the coff-specific initialization routine for reading symbols.
+   It is passed a struct objfile which contains, among other things,
+   the BFD for the file whose symbols are being read, and a slot for
+   a pointer to "private data" which we fill with cookies and other
+   treats for coff_symfile_read ().
+
+   We will only be called if this is a COFF or COFF-like file.
+   BFD handles figuring out the format of the file, and code in symtab.c
+   uses BFD's determination to vector to us.
+
+   The ultimate result is a new symtab (or, FIXME, eventually a psymtab).  */
+
+static void
+coff_symfile_init (struct objfile *objfile)
+{
+  /* Allocate struct to keep track of stab reading. */
+  objfile->sym_stab_info = (struct dbx_symfile_info *)
+    xmmalloc (objfile->md, sizeof (struct dbx_symfile_info));
+
+  memset (objfile->sym_stab_info, 0,
+         sizeof (struct dbx_symfile_info));
+
+  /* Allocate struct to keep track of the symfile */
+  objfile->sym_private = xmmalloc (objfile->md,
+                                  sizeof (struct coff_symfile_info));
+
+  memset (objfile->sym_private, 0, sizeof (struct coff_symfile_info));
+
+  /* COFF objects may be reordered, so set OBJF_REORDERED.  If we
+     find this causes a significant slowdown in gdb then we could
+     set it in the debug symbol readers only when necessary.  */
+  objfile->flags |= OBJF_REORDERED;
+
+  init_entry_point_info (objfile);
+}
+
+/* This function is called for every section; it finds the outer limits
+   of the line table (minimum and maximum file offset) so that the
+   mainline code can read the whole thing for efficiency.  */
+
+/* ARGSUSED */
+static void
+find_linenos (bfd *abfd, sec_ptr asect, void *vpinfo)
+{
+  struct coff_symfile_info *info;
+  int size, count;
+  file_ptr offset, maxoff;
+
+/* WARNING WILL ROBINSON!  ACCESSING BFD-PRIVATE DATA HERE!  FIXME!  */
+  count = asect->lineno_count;
+/* End of warning */
+
+  if (count == 0)
+    return;
+  size = count * local_linesz;
+
+  info = (struct coff_symfile_info *) vpinfo;
+/* WARNING WILL ROBINSON!  ACCESSING BFD-PRIVATE DATA HERE!  FIXME!  */
+  offset = asect->line_filepos;
+/* End of warning */
+
+  if (offset < info->min_lineno_offset || info->min_lineno_offset == 0)
+    info->min_lineno_offset = offset;
+
+  maxoff = offset + size;
+  if (maxoff > info->max_lineno_offset)
+    info->max_lineno_offset = maxoff;
+}
+
+
+/* The BFD for this file -- only good while we're actively reading
+   symbols into a psymtab or a symtab.  */
+
+static bfd *symfile_bfd;
+
+/* Read a symbol file, after initialization by coff_symfile_init.  */
+
+/* ARGSUSED */
+static void
+coff_symfile_read (struct objfile *objfile, int mainline)
+{
+  struct coff_symfile_info *info;
+  struct dbx_symfile_info *dbxinfo;
+  bfd *abfd = objfile->obfd;
+  coff_data_type *cdata = coff_data (abfd);
+  char *name = bfd_get_filename (abfd);
+  register int val;
+  unsigned int num_symbols;
+  int symtab_offset;
+  int stringtab_offset;
+  struct cleanup *back_to;
+  int stabstrsize;
+  int len;
+  char * target;
+  
+  info = (struct coff_symfile_info *) objfile->sym_private;
+  dbxinfo = objfile->sym_stab_info;
+  symfile_bfd = abfd;          /* Kludge for swap routines */
+
+/* WARNING WILL ROBINSON!  ACCESSING BFD-PRIVATE DATA HERE!  FIXME!  */
+  num_symbols = bfd_get_symcount (abfd);       /* How many syms */
+  symtab_offset = cdata->sym_filepos;  /* Symbol table file offset */
+  stringtab_offset = symtab_offset +   /* String table file offset */
+    num_symbols * cdata->local_symesz;
+
+  /* Set a few file-statics that give us specific information about
+     the particular COFF file format we're reading.  */
+  local_n_btmask = cdata->local_n_btmask;
+  local_n_btshft = cdata->local_n_btshft;
+  local_n_tmask = cdata->local_n_tmask;
+  local_n_tshift = cdata->local_n_tshift;
+  local_linesz = cdata->local_linesz;
+  local_symesz = cdata->local_symesz;
+  local_auxesz = cdata->local_auxesz;
+
+  /* Allocate space for raw symbol and aux entries, based on their
+     space requirements as reported by BFD.  */
+  temp_sym = (char *) xmalloc
+    (cdata->local_symesz + cdata->local_auxesz);
+  temp_aux = temp_sym + cdata->local_symesz;
+  back_to = make_cleanup (free_current_contents, &temp_sym);
+
+  /* We need to know whether this is a PE file, because in PE files,
+     unlike standard COFF files, symbol values are stored as offsets
+     from the section address, rather than as absolute addresses.
+     FIXME: We should use BFD to read the symbol table, and thus avoid
+     this problem.  */
+  pe_file =
+    strncmp (bfd_get_target (objfile->obfd), "pe", 2) == 0
+    || strncmp (bfd_get_target (objfile->obfd), "epoc-pe", 7) == 0;
+
+/* End of warning */
+
+  info->min_lineno_offset = 0;
+  info->max_lineno_offset = 0;
+
+  /* Only read line number information if we have symbols.
+
+     On Windows NT, some of the system's DLL's have sections with
+     PointerToLinenumbers fields that are non-zero, but point at
+     random places within the image file.  (In the case I found,
+     KERNEL32.DLL's .text section has a line number info pointer that
+     points into the middle of the string `lib\\i386\kernel32.dll'.)
+
+     However, these DLL's also have no symbols.  The line number
+     tables are meaningless without symbols.  And in fact, GDB never
+     uses the line number information unless there are symbols.  So we
+     can avoid spurious error messages (and maybe run a little
+     faster!) by not even reading the line number table unless we have
+     symbols.  */
+  if (num_symbols > 0)
+    {
+      /* Read the line number table, all at once.  */
+      bfd_map_over_sections (abfd, find_linenos, (void *) info);
+
+      make_cleanup (free_linetab_cleanup, 0 /*ignore*/);
+      val = init_lineno (abfd, info->min_lineno_offset,
+                         info->max_lineno_offset - info->min_lineno_offset);
+      if (val < 0)
+        error ("\"%s\": error reading line numbers\n", name);
+    }
+
+  /* Now read the string table, all at once.  */
+
+  make_cleanup (free_stringtab_cleanup, 0 /*ignore*/);
+  val = init_stringtab (abfd, stringtab_offset);
+  if (val < 0)
+    error ("\"%s\": can't get string table", name);
+
+  init_minimal_symbol_collection ();
+  make_cleanup_discard_minimal_symbols ();
+
+  /* Now that the executable file is positioned at symbol table,
+     process it and define symbols accordingly.  */
+
+  coff_symtab_read ((long) symtab_offset, num_symbols, objfile);
+
+  /* Sort symbols alphabetically within each block.  */
+
+  {
+    struct symtab *s;
+
+    for (s = objfile->symtabs; s != NULL; s = s->next)
+      sort_symtab_syms (s);
+  }
+
+  /* Install any minimal symbols that have been collected as the current
+     minimal symbols for this objfile.  */
+
+  install_minimal_symbols (objfile);
+
+  bfd_map_over_sections (abfd, coff_locate_sections, (void *) info);
+
+  if (info->stabsects)
+    {
+      if (!info->stabstrsect)
+       {
+         error (("The debugging information in `%s' is corrupted.\n"
+                 "The file has a `.stabs' section, but no `.stabstr' "
+                 "section."),
+                name);
+       }
+
+      /* FIXME: dubious.  Why can't we use something normal like
+         bfd_get_section_contents?  */
+      bfd_seek (abfd, abfd->where, 0);
+
+      stabstrsize = bfd_section_size (abfd, info->stabstrsect);
+
+      coffstab_build_psymtabs (objfile,
+                              mainline,
+                              info->textaddr, info->textsize,
+                              info->stabsects,
+                              info->stabstrsect->filepos, stabstrsize);
+    }
+  if (dwarf2_has_info (abfd))
+    {
+      /* DWARF2 sections.  */
+      dwarf2_build_psymtabs (objfile, mainline);
+    }
+
+  do_cleanups (back_to);
+}
+
+static void
+coff_new_init (struct objfile *ignore)
+{
+}
+
+/* Perform any local cleanups required when we are done with a particular
+   objfile.  I.E, we are in the process of discarding all symbol information
+   for an objfile, freeing up all memory held for it, and unlinking the
+   objfile struct from the global list of known objfiles. */
+
+static void
+coff_symfile_finish (struct objfile *objfile)
+{
+  if (objfile->sym_private != NULL)
+    {
+      xmfree (objfile->md, objfile->sym_private);
+    }
+
+  /* Let stabs reader clean up */
+  stabsread_clear_cache ();
+}
+\f
+
+/* Given pointers to a symbol table in coff style exec file,
+   analyze them and create struct symtab's describing the symbols.
+   NSYMS is the number of symbols in the symbol table.
+   We read them one at a time using read_one_sym ().  */
+
+static void
+coff_symtab_read (long symtab_offset, unsigned int nsyms,
+                 struct objfile *objfile)
+{
+  register struct context_stack *new;
+  struct coff_symbol coff_symbol;
+  register struct coff_symbol *cs = &coff_symbol;
+  static struct internal_syment main_sym;
+  static union internal_auxent main_aux;
+  struct coff_symbol fcn_cs_saved;
+  static struct internal_syment fcn_sym_saved;
+  static union internal_auxent fcn_aux_saved;
+  struct symtab *s;
+  /* A .file is open.  */
+  int in_source_file = 0;
+  int next_file_symnum = -1;
+  /* Name of the current file.  */
+  char *filestring = "";
+  int depth = 0;
+  int fcn_first_line = 0;
+  CORE_ADDR fcn_first_line_addr = 0;
+  int fcn_last_line = 0;
+  int fcn_start_addr = 0;
+  long fcn_line_ptr = 0;
+  int val;
+  CORE_ADDR tmpaddr;
+
+  /* Work around a stdio bug in SunOS4.1.1 (this makes me nervous....
+     it's hard to know I've really worked around it.  The fix should be
+     harmless, anyway).  The symptom of the bug is that the first
+     fread (in read_one_sym), will (in my example) actually get data
+     from file offset 268, when the fseek was to 264 (and ftell shows
+     264).  This causes all hell to break loose.  I was unable to
+     reproduce this on a short test program which operated on the same
+     file, performing (I think) the same sequence of operations.
+
+     It stopped happening when I put in this (former) rewind().
+
+     FIXME: Find out if this has been reported to Sun, whether it has
+     been fixed in a later release, etc.  */
+
+  bfd_seek (objfile->obfd, 0, 0);
+
+  /* Position to read the symbol table. */
+  val = bfd_seek (objfile->obfd, (long) symtab_offset, 0);
+  if (val < 0)
+    perror_with_name (objfile->name);
+
+  current_objfile = objfile;
+  nlist_bfd_global = objfile->obfd;
+  nlist_nsyms_global = nsyms;
+  last_source_file = NULL;
+  memset (opaque_type_chain, 0, sizeof opaque_type_chain);
+
+  if (type_vector)             /* Get rid of previous one */
+    xfree (type_vector);
+  type_vector_length = 160;
+  type_vector = (struct type **)
+    xmalloc (type_vector_length * sizeof (struct type *));
+  memset (type_vector, 0, type_vector_length * sizeof (struct type *));
+
+  coff_start_symtab ("");
+
+  symnum = 0;
+  while (symnum < nsyms)
+    {
+      QUIT;                    /* Make this command interruptable.  */
+
+      read_one_sym (cs, &main_sym, &main_aux);
+
+      if (cs->c_symnum == next_file_symnum && cs->c_sclass != C_FILE)
+       {
+         if (last_source_file)
+           coff_end_symtab (objfile);
+
+         coff_start_symtab ("_globals_");
+         complete_symtab ("_globals_", 0, 0);
+         /* done with all files, everything from here on out is globals */
+       }
+
+      /* Special case for file with type declarations only, no text.  */
+      if (!last_source_file && SDB_TYPE (cs->c_type)
+         && cs->c_secnum == N_DEBUG)
+       complete_symtab (filestring, 0, 0);
+
+      /* Typedefs should not be treated as symbol definitions.  */
+      if (ISFCN (cs->c_type) && cs->c_sclass != C_TPDEF)
+       {
+         /* Record all functions -- external and static -- in minsyms. */
+         tmpaddr = cs->c_value + ANOFFSET (objfile->section_offsets, SECT_OFF_TEXT (objfile));
+         record_minimal_symbol (cs->c_name, tmpaddr, mst_text, objfile);
+
+         fcn_line_ptr = main_aux.x_sym.x_fcnary.x_fcn.x_lnnoptr;
+         fcn_start_addr = tmpaddr;
+         fcn_cs_saved = *cs;
+         fcn_sym_saved = main_sym;
+         fcn_aux_saved = main_aux;
+         continue;
+       }
+
+      switch (cs->c_sclass)
+       {
+       case C_EFCN:
+       case C_EXTDEF:
+       case C_ULABEL:
+       case C_USTATIC:
+       case C_LINE:
+       case C_ALIAS:
+       case C_HIDDEN:
+         complain (&bad_sclass_complaint, cs->c_name);
+         break;
+
+       case C_FILE:
+         /* c_value field contains symnum of next .file entry in table
+            or symnum of first global after last .file.  */
+         next_file_symnum = cs->c_value;
+         if (cs->c_naux > 0)
+           filestring = coff_getfilename (&main_aux);
+         else
+           filestring = "";
+
+         /* Complete symbol table for last object file
+            containing debugging information.  */
+         if (last_source_file)
+           {
+             coff_end_symtab (objfile);
+             coff_start_symtab (filestring);
+           }
+         in_source_file = 1;
+         break;
+
+         /* C_LABEL is used for labels and static functions.  Including
+            it here allows gdb to see static functions when no debug
+            info is available.  */
+       case C_LABEL:
+         /* However, labels within a function can make weird backtraces,
+            so filter them out (from phdm@macqel.be). */
+         if (within_function)
+           break;
+       case C_STAT:
+       case C_THUMBLABEL:
+       case C_THUMBSTAT:
+       case C_THUMBSTATFUNC:
+         if (cs->c_name[0] == '.')
+           {
+             if (STREQ (cs->c_name, ".text"))
+               {
+                 /* FIXME:  don't wire in ".text" as section name
+                    or symbol name! */
+                 /* Check for in_source_file deals with case of
+                    a file with debugging symbols
+                    followed by a later file with no symbols.  */
+                 if (in_source_file)
+                   complete_symtab (filestring,
+                   cs->c_value + ANOFFSET (objfile->section_offsets, SECT_OFF_TEXT (objfile)),
+                                    main_aux.x_scn.x_scnlen);
+                 in_source_file = 0;
+               }
+             /* flush rest of '.' symbols */
+             break;
+           }
+         else if (!SDB_TYPE (cs->c_type)
+                  && cs->c_name[0] == 'L'
+                  && (strncmp (cs->c_name, "LI%", 3) == 0
+                      || strncmp (cs->c_name, "LF%", 3) == 0
+                      || strncmp (cs->c_name, "LC%", 3) == 0
+                      || strncmp (cs->c_name, "LP%", 3) == 0
+                      || strncmp (cs->c_name, "LPB%", 4) == 0
+                      || strncmp (cs->c_name, "LBB%", 4) == 0
+                      || strncmp (cs->c_name, "LBE%", 4) == 0
+                      || strncmp (cs->c_name, "LPBX%", 5) == 0))
+           /* At least on a 3b1, gcc generates swbeg and string labels
+              that look like this.  Ignore them.  */
+           break;
+         /* fall in for static symbols that don't start with '.' */
+       case C_THUMBEXT:
+       case C_THUMBEXTFUNC:
+       case C_EXT:
+         {
+           /* Record it in the minimal symbols regardless of
+              SDB_TYPE.  This parallels what we do for other debug
+              formats, and probably is needed to make
+              print_address_symbolic work right without the (now
+              gone) "set fast-symbolic-addr off" kludge.  */
+
+           /* FIXME: should use mst_abs, and not relocate, if absolute.  */
+           enum minimal_symbol_type ms_type;
+           int sec;
+
+           if (cs->c_secnum == N_UNDEF)
+             {
+               /* This is a common symbol.  See if the target
+                  environment knows where it has been relocated to.  */
+               CORE_ADDR reladdr;
+               if (target_lookup_symbol (cs->c_name, &reladdr))
+                 {
+                   /* Error in lookup; ignore symbol.  */
+                   break;
+                 }
+               tmpaddr = reladdr;
+               /* The address has already been relocated; make sure that
+                  objfile_relocate doesn't relocate it again.  */
+               sec = -2;
+               ms_type = cs->c_sclass == C_EXT
+                 || cs->c_sclass == C_THUMBEXT ?
+                 mst_bss : mst_file_bss;
+             }
+           else
+             {
+               sec = cs_to_section (cs, objfile);
+               tmpaddr = cs->c_value;
+               if (cs->c_sclass == C_EXT || cs->c_sclass == C_THUMBEXTFUNC
+                   || cs->c_sclass == C_THUMBEXT)
+                 tmpaddr += ANOFFSET (objfile->section_offsets, sec);
+
+               if (sec == SECT_OFF_TEXT (objfile))
+                 {
+                   ms_type =
+                     cs->c_sclass == C_EXT || cs->c_sclass == C_THUMBEXTFUNC
+                     || cs->c_sclass == C_THUMBEXT ?
+                     mst_text : mst_file_text;
+                   tmpaddr = SMASH_TEXT_ADDRESS (tmpaddr);
+                 }
+               else if (sec == SECT_OFF_DATA (objfile))
+                 {
+                   ms_type =
+                     cs->c_sclass == C_EXT || cs->c_sclass == C_THUMBEXT ?
+                     mst_data : mst_file_data;
+                 }
+               else if (sec == SECT_OFF_BSS (objfile))
+                 {
+                   ms_type =
+                     cs->c_sclass == C_EXT || cs->c_sclass == C_THUMBEXT ?
+                     mst_data : mst_file_data;
+                 }
+               else
+                 ms_type = mst_unknown;
+             }
+
+           if (cs->c_name[0] != '@' /* Skip tdesc symbols */ )
+             {
+               struct minimal_symbol *msym;
+
+               /* FIXME: cagney/2001-02-01: The nasty (int) -> (long)
+                   -> (void*) cast is to ensure that that the value of
+                   cs->c_sclass can be correctly stored in a void
+                   pointer in MSYMBOL_INFO.  Better solutions
+                   welcome. */
+               gdb_assert (sizeof (void *) >= sizeof (cs->c_sclass));
+               msym = prim_record_minimal_symbol_and_info
+                 (cs->c_name, tmpaddr, ms_type, (void *) (long) cs->c_sclass,
+                  sec, NULL, objfile);
+               if (msym)
+                 COFF_MAKE_MSYMBOL_SPECIAL (cs->c_sclass, msym);
+             }
+           if (SDB_TYPE (cs->c_type))
+             {
+               struct symbol *sym;
+               sym = process_coff_symbol
+                 (cs, &main_aux, objfile);
+               SYMBOL_VALUE (sym) = tmpaddr;
+               SYMBOL_SECTION (sym) = sec;
+             }
+         }
+         break;
+
+       case C_FCN:
+         if (STREQ (cs->c_name, ".bf"))
+           {
+             within_function = 1;
+
+             /* value contains address of first non-init type code */
+             /* main_aux.x_sym.x_misc.x_lnsz.x_lnno
+                contains line number of '{' } */
+             if (cs->c_naux != 1)
+               complain (&bf_no_aux_complaint, cs->c_symnum);
+             fcn_first_line = main_aux.x_sym.x_misc.x_lnsz.x_lnno;
+             fcn_first_line_addr = cs->c_value;
+
+             /* Might want to check that locals are 0 and
+                context_stack_depth is zero, and complain if not.  */
+
+             depth = 0;
+             new = push_context (depth, fcn_start_addr);
+             fcn_cs_saved.c_name = getsymname (&fcn_sym_saved);
+             new->name =
+               process_coff_symbol (&fcn_cs_saved, &fcn_aux_saved, objfile);
+           }
+         else if (STREQ (cs->c_name, ".ef"))
+           {
+             if (!within_function)
+               error ("Bad coff function information\n");
+             /* the value of .ef is the address of epilogue code;
+                not useful for gdb.  */
+             /* { main_aux.x_sym.x_misc.x_lnsz.x_lnno
+                contains number of lines to '}' */
+
+             if (context_stack_depth <= 0)
+               {               /* We attempted to pop an empty context stack */
+                 complain (&ef_stack_complaint, cs->c_symnum);
+                 within_function = 0;
+                 break;
+               }
+
+             new = pop_context ();
+             /* Stack must be empty now.  */
+             if (context_stack_depth > 0 || new == NULL)
+               {
+                 complain (&ef_complaint, cs->c_symnum);
+                 within_function = 0;
+                 break;
+               }
+             if (cs->c_naux != 1)
+               {
+                 complain (&ef_no_aux_complaint, cs->c_symnum);
+                 fcn_last_line = 0x7FFFFFFF;
+               }
+             else
+               {
+                 fcn_last_line = main_aux.x_sym.x_misc.x_lnsz.x_lnno;
+               }
+             /* fcn_first_line is the line number of the opening '{'.
+                Do not record it - because it would affect gdb's idea
+                of the line number of the first statement of the function -
+                except for one-line functions, for which it is also the line
+                number of all the statements and of the closing '}', and
+                for which we do not have any other statement-line-number. */
+             if (fcn_last_line == 1)
+               record_line (current_subfile, fcn_first_line,
+                            fcn_first_line_addr);
+             else
+               enter_linenos (fcn_line_ptr, fcn_first_line, fcn_last_line,
+                              objfile);
+
+             finish_block (new->name, &local_symbols, new->old_blocks,
+                           new->start_addr,
+#if defined (FUNCTION_EPILOGUE_SIZE)
+             /* This macro should be defined only on
+                machines where the
+                fcn_aux_saved.x_sym.x_misc.x_fsize
+                field is always zero.
+                So use the .bf record information that
+                points to the epilogue and add the size
+                of the epilogue.  */
+                           cs->c_value
+                           + FUNCTION_EPILOGUE_SIZE
+                           + ANOFFSET (objfile->section_offsets, SECT_OFF_TEXT (objfile)),
+#else
+                           fcn_cs_saved.c_value
+                           + fcn_aux_saved.x_sym.x_misc.x_fsize
+                           + ANOFFSET (objfile->section_offsets, SECT_OFF_TEXT (objfile)),
+#endif
+                           objfile
+               );
+             within_function = 0;
+           }
+         break;
+
+       case C_BLOCK:
+         if (STREQ (cs->c_name, ".bb"))
+           {
+             tmpaddr = cs->c_value;
+             tmpaddr += ANOFFSET (objfile->section_offsets, SECT_OFF_TEXT (objfile));
+             push_context (++depth, tmpaddr);
+           }
+         else if (STREQ (cs->c_name, ".eb"))
+           {
+             if (context_stack_depth <= 0)
+               {               /* We attempted to pop an empty context stack */
+                 complain (&eb_stack_complaint, cs->c_symnum);
+                 break;
+               }
+
+             new = pop_context ();
+             if (depth-- != new->depth)
+               {
+                 complain (&eb_complaint, symnum);
+                 break;
+               }
+             if (local_symbols && context_stack_depth > 0)
+               {
+                 tmpaddr =
+                   cs->c_value + ANOFFSET (objfile->section_offsets, SECT_OFF_TEXT (objfile));
+                 /* Make a block for the local symbols within.  */
+                 finish_block (0, &local_symbols, new->old_blocks,
+                               new->start_addr, tmpaddr, objfile);
+               }
+             /* Now pop locals of block just finished.  */
+             local_symbols = new->locals;
+           }
+         break;
+
+       default:
+         process_coff_symbol (cs, &main_aux, objfile);
+         break;
+       }
+    }
+
+  if (last_source_file)
+    coff_end_symtab (objfile);
+
+  /* Patch up any opaque types (references to types that are not defined
+     in the file where they are referenced, e.g. "struct foo *bar").  */
+  ALL_OBJFILE_SYMTABS (objfile, s)
+    patch_opaque_types (s);
+
+  current_objfile = NULL;
+}
+\f
+/* Routines for reading headers and symbols from executable.  */
+
+/* Read the next symbol, swap it, and return it in both internal_syment
+   form, and coff_symbol form.  Also return its first auxent, if any,
+   in internal_auxent form, and skip any other auxents.  */
+
+static void
+read_one_sym (register struct coff_symbol *cs,
+             register struct internal_syment *sym,
+             register union internal_auxent *aux)
+{
+  int i;
+
+  cs->c_symnum = symnum;
+  bfd_bread (temp_sym, local_symesz, nlist_bfd_global);
+  bfd_coff_swap_sym_in (symfile_bfd, temp_sym, (char *) sym);
+  cs->c_naux = sym->n_numaux & 0xff;
+  if (cs->c_naux >= 1)
+    {
+      bfd_bread (temp_aux, local_auxesz, nlist_bfd_global);
+      bfd_coff_swap_aux_in (symfile_bfd, temp_aux, sym->n_type, sym->n_sclass,
+                           0, cs->c_naux, (char *) aux);
+      /* If more than one aux entry, read past it (only the first aux
+         is important). */
+      for (i = 1; i < cs->c_naux; i++)
+       bfd_bread (temp_aux, local_auxesz, nlist_bfd_global);
+    }
+  cs->c_name = getsymname (sym);
+  cs->c_value = sym->n_value;
+  cs->c_sclass = (sym->n_sclass & 0xff);
+  cs->c_secnum = sym->n_scnum;
+  cs->c_type = (unsigned) sym->n_type;
+  if (!SDB_TYPE (cs->c_type))
+    cs->c_type = 0;
+
+#if 0
+  if (cs->c_sclass & 128)
+    printf ("thumb symbol %s, class 0x%x\n", cs->c_name, cs->c_sclass);
+#endif
+
+  symnum += 1 + cs->c_naux;
+
+  /* The PE file format stores symbol values as offsets within the
+     section, rather than as absolute addresses.  We correct that
+     here, if the symbol has an appropriate storage class.  FIXME: We
+     should use BFD to read the symbols, rather than duplicating the
+     work here.  */
+  if (pe_file)
+    {
+      switch (cs->c_sclass)
+       {
+       case C_EXT:
+       case C_THUMBEXT:
+       case C_THUMBEXTFUNC:
+       case C_SECTION:
+       case C_NT_WEAK:
+       case C_STAT:
+       case C_THUMBSTAT:
+       case C_THUMBSTATFUNC:
+       case C_LABEL:
+       case C_THUMBLABEL:
+       case C_BLOCK:
+       case C_FCN:
+       case C_EFCN:
+         if (cs->c_secnum != 0)
+           cs->c_value += cs_section_address (cs, symfile_bfd);
+         break;
+       }
+    }
+}
+\f
+/* Support for string table handling */
+
+static char *stringtab = NULL;
+
+static int
+init_stringtab (bfd *abfd, long offset)
+{
+  long length;
+  int val;
+  unsigned char lengthbuf[4];
+
+  free_stringtab ();
+
+  /* If the file is stripped, the offset might be zero, indicating no
+     string table.  Just return with `stringtab' set to null. */
+  if (offset == 0)
+    return 0;
+
+  if (bfd_seek (abfd, offset, 0) < 0)
+    return -1;
+
+  val = bfd_bread ((char *) lengthbuf, sizeof lengthbuf, abfd);
+  length = bfd_h_get_32 (symfile_bfd, lengthbuf);
+
+  /* If no string table is needed, then the file may end immediately
+     after the symbols.  Just return with `stringtab' set to null. */
+  if (val != sizeof lengthbuf || length < sizeof lengthbuf)
+    return 0;
+
+  stringtab = (char *) xmalloc (length);
+  /* This is in target format (probably not very useful, and not currently
+     used), not host format.  */
+  memcpy (stringtab, lengthbuf, sizeof lengthbuf);
+  if (length == sizeof length) /* Empty table -- just the count */
+    return 0;
+
+  val = bfd_bread (stringtab + sizeof lengthbuf, length - sizeof lengthbuf,
+                  abfd);
+  if (val != length - sizeof lengthbuf || stringtab[length - 1] != '\0')
+    return -1;
+
+  return 0;
+}
+
+static void
+free_stringtab (void)
+{
+  if (stringtab)
+    xfree (stringtab);
+  stringtab = NULL;
+}
+
+static void
+free_stringtab_cleanup (void *ignore)
+{
+  free_stringtab ();
+}
+
+static char *
+getsymname (struct internal_syment *symbol_entry)
+{
+  static char buffer[SYMNMLEN + 1];
+  char *result;
+
+  if (symbol_entry->_n._n_n._n_zeroes == 0)
+    {
+      /* FIXME: Probably should be detecting corrupt symbol files by
+         seeing whether offset points to within the stringtab.  */
+      result = stringtab + symbol_entry->_n._n_n._n_offset;
+    }
+  else
+    {
+      strncpy (buffer, symbol_entry->_n._n_name, SYMNMLEN);
+      buffer[SYMNMLEN] = '\0';
+      result = buffer;
+    }
+  return result;
+}
+
+/* Extract the file name from the aux entry of a C_FILE symbol.  Return
+   only the last component of the name.  Result is in static storage and
+   is only good for temporary use.  */
+
+static char *
+coff_getfilename (union internal_auxent *aux_entry)
+{
+  static char buffer[BUFSIZ];
+  register char *temp;
+  char *result;
+
+  if (aux_entry->x_file.x_n.x_zeroes == 0)
+    strcpy (buffer, stringtab + aux_entry->x_file.x_n.x_offset);
+  else
+    {
+      strncpy (buffer, aux_entry->x_file.x_fname, FILNMLEN);
+      buffer[FILNMLEN] = '\0';
+    }
+  result = buffer;
+
+  /* FIXME: We should not be throwing away the information about what
+     directory.  It should go into dirname of the symtab, or some such
+     place.  */
+  if ((temp = strrchr (result, '/')) != NULL)
+    result = temp + 1;
+  return (result);
+}
+\f
+/* Support for line number handling.  */
+
+static char *linetab = NULL;
+static long linetab_offset;
+static unsigned long linetab_size;
+
+/* Read in all the line numbers for fast lookups later.  Leave them in
+   external (unswapped) format in memory; we'll swap them as we enter
+   them into GDB's data structures.  */
+
+static int
+init_lineno (bfd *abfd, long offset, int size)
+{
+  int val;
+
+  linetab_offset = offset;
+  linetab_size = size;
+
+  free_linetab ();
+
+  if (size == 0)
+    return 0;
+
+  if (bfd_seek (abfd, offset, 0) < 0)
+    return -1;
+
+  /* Allocate the desired table, plus a sentinel */
+  linetab = (char *) xmalloc (size + local_linesz);
+
+  val = bfd_bread (linetab, size, abfd);
+  if (val != size)
+    return -1;
+
+  /* Terminate it with an all-zero sentinel record */
+  memset (linetab + size, 0, local_linesz);
+
+  return 0;
+}
+
+static void
+free_linetab (void)
+{
+  if (linetab)
+    xfree (linetab);
+  linetab = NULL;
+}
+
+static void
+free_linetab_cleanup (void *ignore)
+{
+  free_linetab ();
+}
+
+#if !defined (L_LNNO32)
+#define L_LNNO32(lp) ((lp)->l_lnno)
+#endif
+
+static void
+enter_linenos (long file_offset, register int first_line,
+              register int last_line, struct objfile *objfile)
+{
+  register char *rawptr;
+  struct internal_lineno lptr;
+
+  if (!linetab)
+    return;
+  if (file_offset < linetab_offset)
+    {
+      complain (&lineno_complaint, file_offset);
+      if (file_offset > linetab_size)  /* Too big to be an offset? */
+       return;
+      file_offset += linetab_offset;   /* Try reading at that linetab offset */
+    }
+
+  rawptr = &linetab[file_offset - linetab_offset];
+
+  /* skip first line entry for each function */
+  rawptr += local_linesz;
+  /* line numbers start at one for the first line of the function */
+  first_line--;
+
+  for (;;)
+    {
+      bfd_coff_swap_lineno_in (symfile_bfd, rawptr, &lptr);
+      rawptr += local_linesz;
+      /* The next function, or the sentinel, will have L_LNNO32 zero; we exit. */
+      if (L_LNNO32 (&lptr) && L_LNNO32 (&lptr) <= last_line)
+       record_line (current_subfile, first_line + L_LNNO32 (&lptr),
+                    lptr.l_addr.l_paddr
+                    + ANOFFSET (objfile->section_offsets, SECT_OFF_TEXT (objfile)));
+      else
+       break;
+    }
+}
+\f
+static void
+patch_type (struct type *type, struct type *real_type)
+{
+  register struct type *target = TYPE_TARGET_TYPE (type);
+  register struct type *real_target = TYPE_TARGET_TYPE (real_type);
+  int field_size = TYPE_NFIELDS (real_target) * sizeof (struct field);
+
+  TYPE_LENGTH (target) = TYPE_LENGTH (real_target);
+  TYPE_NFIELDS (target) = TYPE_NFIELDS (real_target);
+  TYPE_FIELDS (target) = (struct field *) TYPE_ALLOC (target, field_size);
+
+  memcpy (TYPE_FIELDS (target), TYPE_FIELDS (real_target), field_size);
+
+  if (TYPE_NAME (real_target))
+    {
+      if (TYPE_NAME (target))
+       xfree (TYPE_NAME (target));
+      TYPE_NAME (target) = concat (TYPE_NAME (real_target), NULL);
+    }
+}
+
+/* Patch up all appropriate typedef symbols in the opaque_type_chains
+   so that they can be used to print out opaque data structures properly.  */
+
+static void
+patch_opaque_types (struct symtab *s)
+{
+  register struct block *b;
+  register int i;
+  register struct symbol *real_sym;
+
+  /* Go through the per-file symbols only */
+  b = BLOCKVECTOR_BLOCK (BLOCKVECTOR (s), STATIC_BLOCK);
+  ALL_BLOCK_SYMBOLS (b, i, real_sym)
+    {
+      /* Find completed typedefs to use to fix opaque ones.
+         Remove syms from the chain when their types are stored,
+         but search the whole chain, as there may be several syms
+         from different files with the same name.  */
+      if (SYMBOL_CLASS (real_sym) == LOC_TYPEDEF &&
+         SYMBOL_NAMESPACE (real_sym) == VAR_NAMESPACE &&
+         TYPE_CODE (SYMBOL_TYPE (real_sym)) == TYPE_CODE_PTR &&
+         TYPE_LENGTH (TYPE_TARGET_TYPE (SYMBOL_TYPE (real_sym))) != 0)
+       {
+         register char *name = SYMBOL_NAME (real_sym);
+         register int hash = hashname (name);
+         register struct symbol *sym, *prev;
+
+         prev = 0;
+         for (sym = opaque_type_chain[hash]; sym;)
+           {
+             if (name[0] == SYMBOL_NAME (sym)[0] &&
+                 STREQ (name + 1, SYMBOL_NAME (sym) + 1))
+               {
+                 if (prev)
+                   {
+                     SYMBOL_VALUE_CHAIN (prev) = SYMBOL_VALUE_CHAIN (sym);
+                   }
+                 else
+                   {
+                     opaque_type_chain[hash] = SYMBOL_VALUE_CHAIN (sym);
+                   }
+
+                 patch_type (SYMBOL_TYPE (sym), SYMBOL_TYPE (real_sym));
+
+                 if (prev)
+                   {
+                     sym = SYMBOL_VALUE_CHAIN (prev);
+                   }
+                 else
+                   {
+                     sym = opaque_type_chain[hash];
+                   }
+               }
+             else
+               {
+                 prev = sym;
+                 sym = SYMBOL_VALUE_CHAIN (sym);
+               }
+           }
+       }
+    }
+}
+\f
+static struct symbol *
+process_coff_symbol (register struct coff_symbol *cs,
+                    register union internal_auxent *aux,
+                    struct objfile *objfile)
+{
+  register struct symbol *sym
+  = (struct symbol *) obstack_alloc (&objfile->symbol_obstack,
+                                    sizeof (struct symbol));
+  char *name;
+
+  memset (sym, 0, sizeof (struct symbol));
+  name = cs->c_name;
+  name = EXTERNAL_NAME (name, objfile->obfd);
+  SYMBOL_NAME (sym) = obsavestring (name, strlen (name),
+                                   &objfile->symbol_obstack);
+  SYMBOL_LANGUAGE (sym) = language_auto;
+  SYMBOL_INIT_DEMANGLED_NAME (sym, &objfile->symbol_obstack);
+
+  /* default assumptions */
+  SYMBOL_VALUE (sym) = cs->c_value;
+  SYMBOL_NAMESPACE (sym) = VAR_NAMESPACE;
+  SYMBOL_SECTION (sym) = cs_to_section (cs, objfile);
+
+  if (ISFCN (cs->c_type))
+    {
+      SYMBOL_VALUE (sym) += ANOFFSET (objfile->section_offsets, SECT_OFF_TEXT (objfile));
+      SYMBOL_TYPE (sym) =
+       lookup_function_type (decode_function_type (cs, cs->c_type, aux));
+
+      SYMBOL_CLASS (sym) = LOC_BLOCK;
+      if (cs->c_sclass == C_STAT || cs->c_sclass == C_THUMBSTAT
+         || cs->c_sclass == C_THUMBSTATFUNC)
+       add_symbol_to_list (sym, &file_symbols);
+      else if (cs->c_sclass == C_EXT || cs->c_sclass == C_THUMBEXT
+              || cs->c_sclass == C_THUMBEXTFUNC)
+       add_symbol_to_list (sym, &global_symbols);
+    }
+  else
+    {
+      SYMBOL_TYPE (sym) = decode_type (cs, cs->c_type, aux);
+      switch (cs->c_sclass)
+       {
+       case C_NULL:
+         break;
+
+       case C_AUTO:
+         SYMBOL_CLASS (sym) = LOC_LOCAL;
+         add_symbol_to_list (sym, &local_symbols);
+         break;
+
+       case C_THUMBEXT:
+       case C_THUMBEXTFUNC:
+       case C_EXT:
+         SYMBOL_CLASS (sym) = LOC_STATIC;
+         SYMBOL_VALUE_ADDRESS (sym) = (CORE_ADDR) cs->c_value;
+         SYMBOL_VALUE_ADDRESS (sym) += ANOFFSET (objfile->section_offsets, SECT_OFF_TEXT (objfile));
+         add_symbol_to_list (sym, &global_symbols);
+         break;
+
+       case C_THUMBSTAT:
+       case C_THUMBSTATFUNC:
+       case C_STAT:
+         SYMBOL_CLASS (sym) = LOC_STATIC;
+         SYMBOL_VALUE_ADDRESS (sym) = (CORE_ADDR) cs->c_value;
+         SYMBOL_VALUE_ADDRESS (sym) += ANOFFSET (objfile->section_offsets, SECT_OFF_TEXT (objfile));
+         if (within_function)
+           {
+             /* Static symbol of local scope */
+             add_symbol_to_list (sym, &local_symbols);
+           }
+         else
+           {
+             /* Static symbol at top level of file */
+             add_symbol_to_list (sym, &file_symbols);
+           }
+         break;
+
+#ifdef C_GLBLREG               /* AMD coff */
+       case C_GLBLREG:
+#endif
+       case C_REG:
+         SYMBOL_CLASS (sym) = LOC_REGISTER;
+         SYMBOL_VALUE (sym) = SDB_REG_TO_REGNUM (cs->c_value);
+         add_symbol_to_list (sym, &local_symbols);
+         break;
+
+       case C_THUMBLABEL:
+       case C_LABEL:
+         break;
+
+       case C_ARG:
+         SYMBOL_CLASS (sym) = LOC_ARG;
+         add_symbol_to_list (sym, &local_symbols);
+#if !defined (BELIEVE_PCC_PROMOTION)
+         if (TARGET_BYTE_ORDER == BFD_ENDIAN_BIG)
+           {
+             /* If PCC says a parameter is a short or a char,
+                aligned on an int boundary, realign it to the
+                "little end" of the int.  */
+             struct type *temptype;
+             temptype = lookup_fundamental_type (current_objfile,
+                                                 FT_INTEGER);
+             if (TYPE_LENGTH (SYMBOL_TYPE (sym)) < TYPE_LENGTH (temptype)
+                 && TYPE_CODE (SYMBOL_TYPE (sym)) == TYPE_CODE_INT
+                 && 0 == SYMBOL_VALUE (sym) % TYPE_LENGTH (temptype))
+               {
+                 SYMBOL_VALUE (sym) +=
+                   TYPE_LENGTH (temptype)
+                   - TYPE_LENGTH (SYMBOL_TYPE (sym));
+               }
+           }
+#endif
+         break;
+
+       case C_REGPARM:
+         SYMBOL_CLASS (sym) = LOC_REGPARM;
+         SYMBOL_VALUE (sym) = SDB_REG_TO_REGNUM (cs->c_value);
+         add_symbol_to_list (sym, &local_symbols);
+#if !defined (BELIEVE_PCC_PROMOTION)
+         /* FIXME:  This should retain the current type, since it's just
+            a register value.  gnu@adobe, 26Feb93 */
+         {
+           /* If PCC says a parameter is a short or a char,
+              it is really an int.  */
+           struct type *temptype;
+           temptype =
+             lookup_fundamental_type (current_objfile, FT_INTEGER);
+           if (TYPE_LENGTH (SYMBOL_TYPE (sym)) < TYPE_LENGTH (temptype)
+               && TYPE_CODE (SYMBOL_TYPE (sym)) == TYPE_CODE_INT)
+             {
+               SYMBOL_TYPE (sym) =
+                 (TYPE_UNSIGNED (SYMBOL_TYPE (sym))
+                  ? lookup_fundamental_type (current_objfile,
+                                             FT_UNSIGNED_INTEGER)
+                  : temptype);
+             }
+         }
+#endif
+         break;
+
+       case C_TPDEF:
+         SYMBOL_CLASS (sym) = LOC_TYPEDEF;
+         SYMBOL_NAMESPACE (sym) = VAR_NAMESPACE;
+
+         /* If type has no name, give it one */
+         if (TYPE_NAME (SYMBOL_TYPE (sym)) == 0)
+           {
+             if (TYPE_CODE (SYMBOL_TYPE (sym)) == TYPE_CODE_PTR
+                 || TYPE_CODE (SYMBOL_TYPE (sym)) == TYPE_CODE_FUNC)
+               {
+                 /* If we are giving a name to a type such as "pointer to
+                    foo" or "function returning foo", we better not set
+                    the TYPE_NAME.  If the program contains "typedef char
+                    *caddr_t;", we don't want all variables of type char
+                    * to print as caddr_t.  This is not just a
+                    consequence of GDB's type management; CC and GCC (at
+                    least through version 2.4) both output variables of
+                    either type char * or caddr_t with the type
+                    refering to the C_TPDEF symbol for caddr_t.  If a future
+                    compiler cleans this up it GDB is not ready for it
+                    yet, but if it becomes ready we somehow need to
+                    disable this check (without breaking the PCC/GCC2.4
+                    case).
+
+                    Sigh.
+
+                    Fortunately, this check seems not to be necessary
+                    for anything except pointers or functions.  */
+                 ;
+               }
+             else
+               TYPE_NAME (SYMBOL_TYPE (sym)) =
+                 concat (SYMBOL_NAME (sym), NULL);
+           }
+#ifdef CXUX_TARGET
+         /* Ignore vendor section for Harris CX/UX targets. */
+         else if (cs->c_name[0] == '$')
+           break;
+#endif /* CXUX_TARGET */
+
+         /* Keep track of any type which points to empty structured type,
+            so it can be filled from a definition from another file.  A
+            simple forward reference (TYPE_CODE_UNDEF) is not an
+            empty structured type, though; the forward references
+            work themselves out via the magic of coff_lookup_type.  */
+         if (TYPE_CODE (SYMBOL_TYPE (sym)) == TYPE_CODE_PTR &&
+             TYPE_LENGTH (TYPE_TARGET_TYPE (SYMBOL_TYPE (sym))) == 0 &&
+             TYPE_CODE (TYPE_TARGET_TYPE (SYMBOL_TYPE (sym))) !=
+             TYPE_CODE_UNDEF)
+           {
+             register int i = hashname (SYMBOL_NAME (sym));
+
+             SYMBOL_VALUE_CHAIN (sym) = opaque_type_chain[i];
+             opaque_type_chain[i] = sym;
+           }
+         add_symbol_to_list (sym, &file_symbols);
+         break;
+
+       case C_STRTAG:
+       case C_UNTAG:
+       case C_ENTAG:
+         SYMBOL_CLASS (sym) = LOC_TYPEDEF;
+         SYMBOL_NAMESPACE (sym) = STRUCT_NAMESPACE;
+
+         /* Some compilers try to be helpful by inventing "fake"
+            names for anonymous enums, structures, and unions, like
+            "~0fake" or ".0fake".  Thanks, but no thanks... */
+         if (TYPE_TAG_NAME (SYMBOL_TYPE (sym)) == 0)
+           if (SYMBOL_NAME (sym) != NULL
+               && *SYMBOL_NAME (sym) != '~'
+               && *SYMBOL_NAME (sym) != '.')
+             TYPE_TAG_NAME (SYMBOL_TYPE (sym)) =
+               concat (SYMBOL_NAME (sym), NULL);
+
+         add_symbol_to_list (sym, &file_symbols);
+         break;
+
+       default:
+         break;
+       }
+    }
+  return sym;
+}
+\f
+/* Decode a coff type specifier;  return the type that is meant.  */
+
+static struct type *
+decode_type (register struct coff_symbol *cs, unsigned int c_type,
+            register union internal_auxent *aux)
+{
+  register struct type *type = 0;
+  unsigned int new_c_type;
+
+  if (c_type & ~N_BTMASK)
+    {
+      new_c_type = DECREF (c_type);
+      if (ISPTR (c_type))
+       {
+         type = decode_type (cs, new_c_type, aux);
+         type = lookup_pointer_type (type);
+       }
+      else if (ISFCN (c_type))
+       {
+         type = decode_type (cs, new_c_type, aux);
+         type = lookup_function_type (type);
+       }
+      else if (ISARY (c_type))
+       {
+         int i, n;
+         register unsigned short *dim;
+         struct type *base_type, *index_type, *range_type;
+
+         /* Define an array type.  */
+         /* auxent refers to array, not base type */
+         if (aux->x_sym.x_tagndx.l == 0)
+           cs->c_naux = 0;
+
+         /* shift the indices down */
+         dim = &aux->x_sym.x_fcnary.x_ary.x_dimen[0];
+         i = 1;
+         n = dim[0];
+         for (i = 0; *dim && i < DIMNUM - 1; i++, dim++)
+           *dim = *(dim + 1);
+         *dim = 0;
+
+         base_type = decode_type (cs, new_c_type, aux);
+         index_type = lookup_fundamental_type (current_objfile, FT_INTEGER);
+         range_type =
+           create_range_type ((struct type *) NULL, index_type, 0, n - 1);
+         type =
+           create_array_type ((struct type *) NULL, base_type, range_type);
+       }
+      return type;
+    }
+
+  /* Reference to existing type.  This only occurs with the
+     struct, union, and enum types.  EPI a29k coff
+     fakes us out by producing aux entries with a nonzero
+     x_tagndx for definitions of structs, unions, and enums, so we
+     have to check the c_sclass field.  SCO 3.2v4 cc gets confused
+     with pointers to pointers to defined structs, and generates
+     negative x_tagndx fields.  */
+  if (cs->c_naux > 0 && aux->x_sym.x_tagndx.l != 0)
+    {
+      if (cs->c_sclass != C_STRTAG
+         && cs->c_sclass != C_UNTAG
+         && cs->c_sclass != C_ENTAG
+         && aux->x_sym.x_tagndx.l >= 0)
+       {
+         type = coff_alloc_type (aux->x_sym.x_tagndx.l);
+         return type;
+       }
+      else
+       {
+         complain (&tagndx_bad_complaint, cs->c_name);
+         /* And fall through to decode_base_type... */
+       }
+    }
+
+  return decode_base_type (cs, BTYPE (c_type), aux);
+}
+
+/* Decode a coff type specifier for function definition;
+   return the type that the function returns.  */
+
+static struct type *
+decode_function_type (register struct coff_symbol *cs, unsigned int c_type,
+                     register union internal_auxent *aux)
+{
+  if (aux->x_sym.x_tagndx.l == 0)
+    cs->c_naux = 0;            /* auxent refers to function, not base type */
+
+  return decode_type (cs, DECREF (c_type), aux);
+}
+\f
+/* basic C types */
+
+static struct type *
+decode_base_type (register struct coff_symbol *cs, unsigned int c_type,
+                 register union internal_auxent *aux)
+{
+  struct type *type;
+
+  switch (c_type)
+    {
+    case T_NULL:
+      /* shows up with "void (*foo)();" structure members */
+      return lookup_fundamental_type (current_objfile, FT_VOID);
+
+#if 0
+/* DGUX actually defines both T_ARG and T_VOID to the same value.  */
+#ifdef T_ARG
+    case T_ARG:
+      /* Shows up in DGUX, I think.  Not sure where.  */
+      return lookup_fundamental_type (current_objfile, FT_VOID);       /* shouldn't show up here */
+#endif
+#endif /* 0 */
+
+#ifdef T_VOID
+    case T_VOID:
+      /* Intel 960 COFF has this symbol and meaning.  */
+      return lookup_fundamental_type (current_objfile, FT_VOID);
+#endif
+
+    case T_CHAR:
+      return lookup_fundamental_type (current_objfile, FT_CHAR);
+
+    case T_SHORT:
+      return lookup_fundamental_type (current_objfile, FT_SHORT);
+
+    case T_INT:
+      return lookup_fundamental_type (current_objfile, FT_INTEGER);
+
+    case T_LONG:
+      if (cs->c_sclass == C_FIELD
+         && aux->x_sym.x_misc.x_lnsz.x_size > TARGET_LONG_BIT)
+       return lookup_fundamental_type (current_objfile, FT_LONG_LONG);
+      else
+       return lookup_fundamental_type (current_objfile, FT_LONG);
+
+    case T_FLOAT:
+      return lookup_fundamental_type (current_objfile, FT_FLOAT);
+
+    case T_DOUBLE:
+      return lookup_fundamental_type (current_objfile, FT_DBL_PREC_FLOAT);
+
+    case T_LNGDBL:
+      return lookup_fundamental_type (current_objfile, FT_EXT_PREC_FLOAT);
+
+    case T_STRUCT:
+      if (cs->c_naux != 1)
+       {
+         /* anonymous structure type */
+         type = coff_alloc_type (cs->c_symnum);
+         TYPE_CODE (type) = TYPE_CODE_STRUCT;
+         TYPE_NAME (type) = NULL;
+         /* This used to set the tag to "<opaque>".  But I think setting it
+            to NULL is right, and the printing code can print it as
+            "struct {...}".  */
+         TYPE_TAG_NAME (type) = NULL;
+         INIT_CPLUS_SPECIFIC (type);
+         TYPE_LENGTH (type) = 0;
+         TYPE_FIELDS (type) = 0;
+         TYPE_NFIELDS (type) = 0;
+       }
+      else
+       {
+         type = coff_read_struct_type (cs->c_symnum,
+                                       aux->x_sym.x_misc.x_lnsz.x_size,
+                                     aux->x_sym.x_fcnary.x_fcn.x_endndx.l);
+       }
+      return type;
+
+    case T_UNION:
+      if (cs->c_naux != 1)
+       {
+         /* anonymous union type */
+         type = coff_alloc_type (cs->c_symnum);
+         TYPE_NAME (type) = NULL;
+         /* This used to set the tag to "<opaque>".  But I think setting it
+            to NULL is right, and the printing code can print it as
+            "union {...}".  */
+         TYPE_TAG_NAME (type) = NULL;
+         INIT_CPLUS_SPECIFIC (type);
+         TYPE_LENGTH (type) = 0;
+         TYPE_FIELDS (type) = 0;
+         TYPE_NFIELDS (type) = 0;
+       }
+      else
+       {
+         type = coff_read_struct_type (cs->c_symnum,
+                                       aux->x_sym.x_misc.x_lnsz.x_size,
+                                     aux->x_sym.x_fcnary.x_fcn.x_endndx.l);
+       }
+      TYPE_CODE (type) = TYPE_CODE_UNION;
+      return type;
+
+    case T_ENUM:
+      if (cs->c_naux != 1)
+       {
+         /* anonymous enum type */
+         type = coff_alloc_type (cs->c_symnum);
+         TYPE_CODE (type) = TYPE_CODE_ENUM;
+         TYPE_NAME (type) = NULL;
+         /* This used to set the tag to "<opaque>".  But I think setting it
+            to NULL is right, and the printing code can print it as
+            "enum {...}".  */
+         TYPE_TAG_NAME (type) = NULL;
+         TYPE_LENGTH (type) = 0;
+         TYPE_FIELDS (type) = 0;
+         TYPE_NFIELDS (type) = 0;
+       }
+      else
+       {
+         type = coff_read_enum_type (cs->c_symnum,
+                                     aux->x_sym.x_misc.x_lnsz.x_size,
+                                     aux->x_sym.x_fcnary.x_fcn.x_endndx.l);
+       }
+      return type;
+
+    case T_MOE:
+      /* shouldn't show up here */
+      break;
+
+    case T_UCHAR:
+      return lookup_fundamental_type (current_objfile, FT_UNSIGNED_CHAR);
+
+    case T_USHORT:
+      return lookup_fundamental_type (current_objfile, FT_UNSIGNED_SHORT);
+
+    case T_UINT:
+      return lookup_fundamental_type (current_objfile, FT_UNSIGNED_INTEGER);
+
+    case T_ULONG:
+      if (cs->c_sclass == C_FIELD
+         && aux->x_sym.x_misc.x_lnsz.x_size > TARGET_LONG_BIT)
+       return lookup_fundamental_type (current_objfile, FT_UNSIGNED_LONG_LONG);
+      else
+       return lookup_fundamental_type (current_objfile, FT_UNSIGNED_LONG);
+    }
+  complain (&unexpected_type_complaint, cs->c_name);
+  return lookup_fundamental_type (current_objfile, FT_VOID);
+}
+\f
+/* This page contains subroutines of read_type.  */
+
+/* Read the description of a structure (or union type) and return an
+   object describing the type.  */
+
+static struct type *
+coff_read_struct_type (int index, int length, int lastsym)
+{
+  struct nextfield
+    {
+      struct nextfield *next;
+      struct field field;
+    };
+
+  register struct type *type;
+  register struct nextfield *list = 0;
+  struct nextfield *new;
+  int nfields = 0;
+  register int n;
+  char *name;
+  struct coff_symbol member_sym;
+  register struct coff_symbol *ms = &member_sym;
+  struct internal_syment sub_sym;
+  union internal_auxent sub_aux;
+  int done = 0;
+
+  type = coff_alloc_type (index);
+  TYPE_CODE (type) = TYPE_CODE_STRUCT;
+  INIT_CPLUS_SPECIFIC (type);
+  TYPE_LENGTH (type) = length;
+
+  while (!done && symnum < lastsym && symnum < nlist_nsyms_global)
+    {
+      read_one_sym (ms, &sub_sym, &sub_aux);
+      name = ms->c_name;
+      name = EXTERNAL_NAME (name, current_objfile->obfd);
+
+      switch (ms->c_sclass)
+       {
+       case C_MOS:
+       case C_MOU:
+
+         /* Get space to record the next field's data.  */
+         new = (struct nextfield *) alloca (sizeof (struct nextfield));
+         new->next = list;
+         list = new;
+
+         /* Save the data.  */
+         list->field.name =
+           obsavestring (name,
+                         strlen (name),
+                         &current_objfile->symbol_obstack);
+         FIELD_TYPE (list->field) = decode_type (ms, ms->c_type, &sub_aux);
+         FIELD_BITPOS (list->field) = 8 * ms->c_value;
+         FIELD_BITSIZE (list->field) = 0;
+         nfields++;
+         break;
+
+       case C_FIELD:
+
+         /* Get space to record the next field's data.  */
+         new = (struct nextfield *) alloca (sizeof (struct nextfield));
+         new->next = list;
+         list = new;
+
+         /* Save the data.  */
+         list->field.name =
+           obsavestring (name,
+                         strlen (name),
+                         &current_objfile->symbol_obstack);
+         FIELD_TYPE (list->field) = decode_type (ms, ms->c_type, &sub_aux);
+         FIELD_BITPOS (list->field) = ms->c_value;
+         FIELD_BITSIZE (list->field) = sub_aux.x_sym.x_misc.x_lnsz.x_size;
+         nfields++;
+         break;
+
+       case C_EOS:
+         done = 1;
+         break;
+       }
+    }
+  /* Now create the vector of fields, and record how big it is.  */
+
+  TYPE_NFIELDS (type) = nfields;
+  TYPE_FIELDS (type) = (struct field *)
+    TYPE_ALLOC (type, sizeof (struct field) * nfields);
+
+  /* Copy the saved-up fields into the field vector.  */
+
+  for (n = nfields; list; list = list->next)
+    TYPE_FIELD (type, --n) = list->field;
+
+  return type;
+}
+\f
+/* Read a definition of an enumeration type,
+   and create and return a suitable type object.
+   Also defines the symbols that represent the values of the type.  */
+
+/* ARGSUSED */
+static struct type *
+coff_read_enum_type (int index, int length, int lastsym)
+{
+  register struct symbol *sym;
+  register struct type *type;
+  int nsyms = 0;
+  int done = 0;
+  struct pending **symlist;
+  struct coff_symbol member_sym;
+  register struct coff_symbol *ms = &member_sym;
+  struct internal_syment sub_sym;
+  union internal_auxent sub_aux;
+  struct pending *osyms, *syms;
+  int o_nsyms;
+  register int n;
+  char *name;
+  int unsigned_enum = 1;
+
+  type = coff_alloc_type (index);
+  if (within_function)
+    symlist = &local_symbols;
+  else
+    symlist = &file_symbols;
+  osyms = *symlist;
+  o_nsyms = osyms ? osyms->nsyms : 0;
+
+  while (!done && symnum < lastsym && symnum < nlist_nsyms_global)
+    {
+      read_one_sym (ms, &sub_sym, &sub_aux);
+      name = ms->c_name;
+      name = EXTERNAL_NAME (name, current_objfile->obfd);
+
+      switch (ms->c_sclass)
+       {
+       case C_MOE:
+         sym = (struct symbol *) obstack_alloc
+           (&current_objfile->symbol_obstack,
+            sizeof (struct symbol));
+         memset (sym, 0, sizeof (struct symbol));
+
+         SYMBOL_NAME (sym) =
+           obsavestring (name, strlen (name),
+                         &current_objfile->symbol_obstack);
+         SYMBOL_CLASS (sym) = LOC_CONST;
+         SYMBOL_NAMESPACE (sym) = VAR_NAMESPACE;
+         SYMBOL_VALUE (sym) = ms->c_value;
+         add_symbol_to_list (sym, symlist);
+         nsyms++;
+         break;
+
+       case C_EOS:
+         /* Sometimes the linker (on 386/ix 2.0.2 at least) screws
+            up the count of how many symbols to read.  So stop
+            on .eos.  */
+         done = 1;
+         break;
+       }
+    }
+
+  /* Now fill in the fields of the type-structure.  */
+
+  if (length > 0)
+    TYPE_LENGTH (type) = length;
+  else
+    TYPE_LENGTH (type) = TARGET_INT_BIT / TARGET_CHAR_BIT;     /* Assume ints */
+  TYPE_CODE (type) = TYPE_CODE_ENUM;
+  TYPE_NFIELDS (type) = nsyms;
+  TYPE_FIELDS (type) = (struct field *)
+    TYPE_ALLOC (type, sizeof (struct field) * nsyms);
+
+  /* Find the symbols for the values and put them into the type.
+     The symbols can be found in the symlist that we put them on
+     to cause them to be defined.  osyms contains the old value
+     of that symlist; everything up to there was defined by us.  */
+  /* Note that we preserve the order of the enum constants, so
+     that in something like "enum {FOO, LAST_THING=FOO}" we print
+     FOO, not LAST_THING.  */
+
+  for (syms = *symlist, n = 0; syms; syms = syms->next)
+    {
+      int j = 0;
+
+      if (syms == osyms)
+       j = o_nsyms;
+      for (; j < syms->nsyms; j++, n++)
+       {
+         struct symbol *xsym = syms->symbol[j];
+         SYMBOL_TYPE (xsym) = type;
+         TYPE_FIELD_NAME (type, n) = SYMBOL_NAME (xsym);
+         TYPE_FIELD_BITPOS (type, n) = SYMBOL_VALUE (xsym);
+         if (SYMBOL_VALUE (xsym) < 0)
+           unsigned_enum = 0;
+         TYPE_FIELD_BITSIZE (type, n) = 0;
+       }
+      if (syms == osyms)
+       break;
+    }
+
+  if (unsigned_enum)
+    TYPE_FLAGS (type) |= TYPE_FLAG_UNSIGNED;
+
+  return type;
+}
+
+/* Register our ability to parse symbols for coff BFD files. */
+
+static struct sym_fns coff_sym_fns =
+{
+  bfd_target_coff_flavour,
+  coff_new_init,               /* sym_new_init: init anything gbl to entire symtab */
+  coff_symfile_init,           /* sym_init: read initial info, setup for sym_read() */
+  coff_symfile_read,           /* sym_read: read a symbol file into symtab */
+  coff_symfile_finish,         /* sym_finish: finished with file, cleanup */
+  default_symfile_offsets,     /* sym_offsets:  xlate external to internal form */
+  NULL                         /* next: pointer to next struct sym_fns */
+};
+
+void
+_initialize_coffread (void)
+{
+  add_symtab_fns (&coff_sym_fns);
+}
diff --git a/gdb/dbxread.c b/gdb/dbxread.c
new file mode 100644 (file)
index 0000000..6592b74
--- /dev/null
@@ -0,0 +1,3599 @@
+/* Read dbx symbol tables and convert to internal format, for GDB.
+   Copyright 1986, 1987, 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1995,
+   1996, 1997, 1998, 1999, 2000, 2001, 2002
+   Free Software Foundation, Inc.
+
+   This file is part of GDB.
+
+   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 module provides three functions: dbx_symfile_init,
+   which initializes to read a symbol file; dbx_new_init, which 
+   discards existing cached information when all symbols are being
+   discarded; and dbx_symfile_read, which reads a symbol table
+   from a file.
+
+   dbx_symfile_read only does the minimum work necessary for letting the
+   user "name" things symbolically; it does not read the entire symtab.
+   Instead, it reads the external and static symbols and puts them in partial
+   symbol tables.  When more extensive information is requested of a
+   file, the corresponding partial symbol table is mutated into a full
+   fledged symbol table by going back and reading the symbols
+   for real.  dbx_psymtab_to_symtab() is the function that does this */
+
+#include "defs.h"
+#include "gdb_string.h"
+
+#if defined(USG) || defined(__CYGNUSCLIB__)
+#include <sys/types.h>
+#include <fcntl.h>
+#endif
+
+#include "gdb_obstack.h"
+#include "gdb_stat.h"
+#include "symtab.h"
+#include "breakpoint.h"
+#include "target.h"
+#include "gdbcore.h"           /* for bfd stuff */
+#include "libaout.h"           /* FIXME Secret internal BFD stuff for a.out */
+#include "symfile.h"
+#include "objfiles.h"
+#include "buildsym.h"
+#include "stabsread.h"
+#include "gdb-stabs.h"
+#include "demangle.h"
+#include "language.h"          /* Needed for local_hex_string */
+#include "complaints.h"
+#include "cp-abi.h"
+
+#include "aout/aout64.h"
+#include "aout/stab_gnu.h"     /* We always use GNU stabs, not native, now */
+\f
+
+/* This macro returns the size field of a minimal symbol, which is normally
+   stored in the "info" field.  The macro can be overridden for specific
+   targets (e.g. MIPS16) that use the info field for other purposes.  */
+#ifndef MSYMBOL_SIZE
+#define MSYMBOL_SIZE(msym) ((long) MSYMBOL_INFO (msym))
+#endif
+
+
+/* We put a pointer to this structure in the read_symtab_private field
+   of the psymtab.  */
+
+struct symloc
+  {
+    /* Offset within the file symbol table of first local symbol for this
+       file.  */
+
+    int ldsymoff;
+
+    /* Length (in bytes) of the section of the symbol table devoted to
+       this file's symbols (actually, the section bracketed may contain
+       more than just this file's symbols).  If ldsymlen is 0, the only
+       reason for this thing's existence is the dependency list.  Nothing
+       else will happen when it is read in.  */
+
+    int ldsymlen;
+
+    /* The size of each symbol in the symbol file (in external form).  */
+
+    int symbol_size;
+
+    /* Further information needed to locate the symbols if they are in
+       an ELF file.  */
+
+    int symbol_offset;
+    int string_offset;
+    int file_string_offset;
+  };
+
+#define LDSYMOFF(p) (((struct symloc *)((p)->read_symtab_private))->ldsymoff)
+#define LDSYMLEN(p) (((struct symloc *)((p)->read_symtab_private))->ldsymlen)
+#define SYMLOC(p) ((struct symloc *)((p)->read_symtab_private))
+#define SYMBOL_SIZE(p) (SYMLOC(p)->symbol_size)
+#define SYMBOL_OFFSET(p) (SYMLOC(p)->symbol_offset)
+#define STRING_OFFSET(p) (SYMLOC(p)->string_offset)
+#define FILE_STRING_OFFSET(p) (SYMLOC(p)->file_string_offset)
+\f
+
+/* Remember what we deduced to be the source language of this psymtab. */
+
+static enum language psymtab_language = language_unknown;
+
+/* The BFD for this file -- implicit parameter to next_symbol_text.  */
+
+static bfd *symfile_bfd;
+
+/* The size of each symbol in the symbol file (in external form).
+   This is set by dbx_symfile_read when building psymtabs, and by
+   dbx_psymtab_to_symtab when building symtabs.  */
+
+static unsigned symbol_size;
+
+/* This is the offset of the symbol table in the executable file. */
+
+static unsigned symbol_table_offset;
+
+/* This is the offset of the string table in the executable file. */
+
+static unsigned string_table_offset;
+
+/* For elf+stab executables, the n_strx field is not a simple index
+   into the string table.  Instead, each .o file has a base offset in
+   the string table, and the associated symbols contain offsets from
+   this base.  The following two variables contain the base offset for
+   the current and next .o files. */
+
+static unsigned int file_string_table_offset;
+static unsigned int next_file_string_table_offset;
+
+/* .o and NLM files contain unrelocated addresses which are based at
+   0.  When non-zero, this flag disables some of the special cases for
+   Solaris elf+stab text addresses at location 0. */
+
+static int symfile_relocatable = 0;
+
+/* If this is nonzero, N_LBRAC, N_RBRAC, and N_SLINE entries are
+   relative to the function start address.  */
+
+static int block_address_function_relative = 0;
+\f
+/* The lowest text address we have yet encountered.  This is needed
+   because in an a.out file, there is no header field which tells us
+   what address the program is actually going to be loaded at, so we
+   need to make guesses based on the symbols (which *are* relocated to
+   reflect the address it will be loaded at).  */
+
+static CORE_ADDR lowest_text_address;
+
+/* Non-zero if there is any line number info in the objfile.  Prevents
+   end_psymtab from discarding an otherwise empty psymtab.  */
+
+static int has_line_numbers;
+
+/* Complaints about the symbols we have encountered.  */
+
+struct complaint lbrac_complaint =
+{"bad block start address patched", 0, 0};
+
+struct complaint string_table_offset_complaint =
+{"bad string table offset in symbol %d", 0, 0};
+
+struct complaint unknown_symtype_complaint =
+{"unknown symbol type %s", 0, 0};
+
+struct complaint unknown_symchar_complaint =
+{"unknown symbol descriptor `%c'", 0, 0};
+
+struct complaint lbrac_rbrac_complaint =
+{"block start larger than block end", 0, 0};
+
+struct complaint lbrac_unmatched_complaint =
+{"unmatched N_LBRAC before symtab pos %d", 0, 0};
+
+struct complaint lbrac_mismatch_complaint =
+{"N_LBRAC/N_RBRAC symbol mismatch at symtab pos %d", 0, 0};
+
+struct complaint repeated_header_complaint =
+{"\"repeated\" header file %s not previously seen, at symtab pos %d", 0, 0};
+
+struct complaint unclaimed_bincl_complaint =
+{"N_BINCL %s not in entries for any file, at symtab pos %d", 0, 0};
+
+struct complaint discarding_local_symbols_complaint =
+{"misplaced N_LBRAC entry; discarding local symbols which have no enclosing block", 0, 0};
+\f
+/* find_text_range --- find start and end of loadable code sections
+
+   The find_text_range function finds the shortest address range that
+   encloses all sections containing executable code, and stores it in
+   objfile's text_addr and text_size members.
+
+   dbx_symfile_read will use this to finish off the partial symbol
+   table, in some cases.  */
+
+static void
+find_text_range (bfd * sym_bfd, struct objfile *objfile)
+{
+  asection *sec;
+  int found_any = 0;
+  CORE_ADDR start = 0;
+  CORE_ADDR end = 0;
+
+  for (sec = sym_bfd->sections; sec; sec = sec->next)
+    if (bfd_get_section_flags (sym_bfd, sec) & SEC_CODE)
+      {
+       CORE_ADDR sec_start = bfd_section_vma (sym_bfd, sec);
+       CORE_ADDR sec_end = sec_start + bfd_section_size (sym_bfd, sec);
+
+       if (found_any)
+         {
+           if (sec_start < start)
+             start = sec_start;
+           if (sec_end > end)
+             end = sec_end;
+         }
+       else
+         {
+           start = sec_start;
+           end = sec_end;
+         }
+
+       found_any = 1;
+      }
+
+  if (!found_any)
+    error ("Can't find any code sections in symbol file");
+
+  DBX_TEXT_ADDR (objfile) = start;
+  DBX_TEXT_SIZE (objfile) = end - start;
+}
+\f
+
+
+/* During initial symbol readin, we need to have a structure to keep
+   track of which psymtabs have which bincls in them.  This structure
+   is used during readin to setup the list of dependencies within each
+   partial symbol table. */
+
+struct header_file_location
+{
+  char *name;                  /* Name of header file */
+  int instance;                        /* See above */
+  struct partial_symtab *pst;  /* Partial symtab that has the
+                                  BINCL/EINCL defs for this file */
+};
+
+/* The actual list and controling variables */
+static struct header_file_location *bincl_list, *next_bincl;
+static int bincls_allocated;
+
+/* Local function prototypes */
+
+extern void _initialize_dbxread (void);
+
+static void process_now (struct objfile *);
+
+static void read_ofile_symtab (struct partial_symtab *);
+
+static void dbx_psymtab_to_symtab (struct partial_symtab *);
+
+static void dbx_psymtab_to_symtab_1 (struct partial_symtab *);
+
+static void read_dbx_dynamic_symtab (struct objfile *objfile);
+
+static void read_dbx_symtab (struct objfile *);
+
+static void free_bincl_list (struct objfile *);
+
+static struct partial_symtab *find_corresponding_bincl_psymtab (char *, int);
+
+static void add_bincl_to_list (struct partial_symtab *, char *, int);
+
+static void init_bincl_list (int, struct objfile *);
+
+static char *dbx_next_symbol_text (struct objfile *);
+
+static void fill_symbuf (bfd *);
+
+static void dbx_symfile_init (struct objfile *);
+
+static void dbx_new_init (struct objfile *);
+
+static void dbx_symfile_read (struct objfile *, int);
+
+static void dbx_symfile_finish (struct objfile *);
+
+static void record_minimal_symbol (char *, CORE_ADDR, int, struct objfile *);
+
+static void add_new_header_file (char *, int);
+
+static void add_old_header_file (char *, int);
+
+static void add_this_object_header_file (int);
+
+static struct partial_symtab *start_psymtab (struct objfile *, char *,
+                                            CORE_ADDR, int,
+                                            struct partial_symbol **,
+                                            struct partial_symbol **);
+
+/* Free up old header file tables */
+
+void
+free_header_files (void)
+{
+  if (this_object_header_files)
+    {
+      xfree (this_object_header_files);
+      this_object_header_files = NULL;
+    }
+  n_allocated_this_object_header_files = 0;
+}
+
+/* Allocate new header file tables */
+
+void
+init_header_files (void)
+{
+  n_allocated_this_object_header_files = 10;
+  this_object_header_files = (int *) xmalloc (10 * sizeof (int));
+}
+
+/* Add header file number I for this object file
+   at the next successive FILENUM.  */
+
+static void
+add_this_object_header_file (int i)
+{
+  if (n_this_object_header_files == n_allocated_this_object_header_files)
+    {
+      n_allocated_this_object_header_files *= 2;
+      this_object_header_files
+       = (int *) xrealloc ((char *) this_object_header_files,
+                      n_allocated_this_object_header_files * sizeof (int));
+    }
+
+  this_object_header_files[n_this_object_header_files++] = i;
+}
+
+/* Add to this file an "old" header file, one already seen in
+   a previous object file.  NAME is the header file's name.
+   INSTANCE is its instance code, to select among multiple
+   symbol tables for the same header file.  */
+
+static void
+add_old_header_file (char *name, int instance)
+{
+  register struct header_file *p = HEADER_FILES (current_objfile);
+  register int i;
+
+  for (i = 0; i < N_HEADER_FILES (current_objfile); i++)
+    if (STREQ (p[i].name, name) && instance == p[i].instance)
+      {
+       add_this_object_header_file (i);
+       return;
+      }
+  complain (&repeated_header_complaint, name, symnum);
+}
+
+/* Add to this file a "new" header file: definitions for its types follow.
+   NAME is the header file's name.
+   Most often this happens only once for each distinct header file,
+   but not necessarily.  If it happens more than once, INSTANCE has
+   a different value each time, and references to the header file
+   use INSTANCE values to select among them.
+
+   dbx output contains "begin" and "end" markers for each new header file,
+   but at this level we just need to know which files there have been;
+   so we record the file when its "begin" is seen and ignore the "end".  */
+
+static void
+add_new_header_file (char *name, int instance)
+{
+  register int i;
+  register struct header_file *hfile;
+
+  /* Make sure there is room for one more header file.  */
+
+  i = N_ALLOCATED_HEADER_FILES (current_objfile);
+
+  if (N_HEADER_FILES (current_objfile) == i)
+    {
+      if (i == 0)
+       {
+         N_ALLOCATED_HEADER_FILES (current_objfile) = 10;
+         HEADER_FILES (current_objfile) = (struct header_file *)
+           xmalloc (10 * sizeof (struct header_file));
+       }
+      else
+       {
+         i *= 2;
+         N_ALLOCATED_HEADER_FILES (current_objfile) = i;
+         HEADER_FILES (current_objfile) = (struct header_file *)
+           xrealloc ((char *) HEADER_FILES (current_objfile),
+                     (i * sizeof (struct header_file)));
+       }
+    }
+
+  /* Create an entry for this header file.  */
+
+  i = N_HEADER_FILES (current_objfile)++;
+  hfile = HEADER_FILES (current_objfile) + i;
+  hfile->name = savestring (name, strlen (name));
+  hfile->instance = instance;
+  hfile->length = 10;
+  hfile->vector
+    = (struct type **) xmalloc (10 * sizeof (struct type *));
+  memset (hfile->vector, 0, 10 * sizeof (struct type *));
+
+  add_this_object_header_file (i);
+}
+
+#if 0
+static struct type **
+explicit_lookup_type (int real_filenum, int index)
+{
+  register struct header_file *f = &HEADER_FILES (current_objfile)[real_filenum];
+
+  if (index >= f->length)
+    {
+      f->length *= 2;
+      f->vector = (struct type **)
+       xrealloc (f->vector, f->length * sizeof (struct type *));
+      memset (&f->vector[f->length / 2],
+             '\0', f->length * sizeof (struct type *) / 2);
+    }
+  return &f->vector[index];
+}
+#endif
+\f
+static void
+record_minimal_symbol (char *name, CORE_ADDR address, int type,
+                      struct objfile *objfile)
+{
+  enum minimal_symbol_type ms_type;
+  int section;
+  asection *bfd_section;
+
+  switch (type)
+    {
+    case N_TEXT | N_EXT:
+      ms_type = mst_text;
+      section = SECT_OFF_TEXT (objfile);
+      bfd_section = DBX_TEXT_SECTION (objfile);
+      break;
+    case N_DATA | N_EXT:
+      ms_type = mst_data;
+      section = SECT_OFF_DATA (objfile);
+      bfd_section = DBX_DATA_SECTION (objfile);
+      break;
+    case N_BSS | N_EXT:
+      ms_type = mst_bss;
+      section = SECT_OFF_BSS (objfile);
+      bfd_section = DBX_BSS_SECTION (objfile);
+      break;
+    case N_ABS | N_EXT:
+      ms_type = mst_abs;
+      section = -1;
+      bfd_section = NULL;
+      break;
+#ifdef N_SETV
+    case N_SETV | N_EXT:
+      ms_type = mst_data;
+      section = SECT_OFF_DATA (objfile);
+      bfd_section = DBX_DATA_SECTION (objfile);
+      break;
+    case N_SETV:
+      /* I don't think this type actually exists; since a N_SETV is the result
+         of going over many .o files, it doesn't make sense to have one
+         file local.  */
+      ms_type = mst_file_data;
+      section = SECT_OFF_DATA (objfile);
+      bfd_section = DBX_DATA_SECTION (objfile);
+      break;
+#endif
+    case N_TEXT:
+    case N_NBTEXT:
+    case N_FN:
+    case N_FN_SEQ:
+      ms_type = mst_file_text;
+      section = SECT_OFF_TEXT (objfile);
+      bfd_section = DBX_TEXT_SECTION (objfile);
+      break;
+    case N_DATA:
+      ms_type = mst_file_data;
+
+      /* Check for __DYNAMIC, which is used by Sun shared libraries. 
+         Record it as global even if it's local, not global, so
+         lookup_minimal_symbol can find it.  We don't check symbol_leading_char
+         because for SunOS4 it always is '_'.  */
+      if (name[8] == 'C' && STREQ ("__DYNAMIC", name))
+       ms_type = mst_data;
+
+      /* Same with virtual function tables, both global and static.  */
+      {
+       char *tempstring = name;
+       if (tempstring[0] == bfd_get_symbol_leading_char (objfile->obfd))
+         ++tempstring;
+       if (is_vtable_name (tempstring))
+         ms_type = mst_data;
+      }
+      section = SECT_OFF_DATA (objfile);
+      bfd_section = DBX_DATA_SECTION (objfile);
+      break;
+    case N_BSS:
+      ms_type = mst_file_bss;
+      section = SECT_OFF_BSS (objfile);
+      bfd_section = DBX_BSS_SECTION (objfile);
+      break;
+    default:
+      ms_type = mst_unknown;
+      section = -1;
+      bfd_section = NULL;
+      break;
+    }
+
+  if ((ms_type == mst_file_text || ms_type == mst_text)
+      && address < lowest_text_address)
+    lowest_text_address = address;
+
+  prim_record_minimal_symbol_and_info
+    (name, address, ms_type, NULL, section, bfd_section, objfile);
+}
+\f
+/* Scan and build partial symbols for a symbol file.
+   We have been initialized by a call to dbx_symfile_init, which 
+   put all the relevant info into a "struct dbx_symfile_info",
+   hung off the objfile structure.
+
+   MAINLINE is true if we are reading the main symbol
+   table (as opposed to a shared lib or dynamically loaded file).  */
+
+static void
+dbx_symfile_read (struct objfile *objfile, int mainline)
+{
+  bfd *sym_bfd;
+  int val;
+  struct cleanup *back_to;
+
+  sym_bfd = objfile->obfd;
+
+  /* .o and .nlm files are relocatables with text, data and bss segs based at
+     0.  This flag disables special (Solaris stabs-in-elf only) fixups for
+     symbols with a value of 0.  */
+
+  symfile_relocatable = bfd_get_file_flags (sym_bfd) & HAS_RELOC;
+
+  /* This is true for Solaris (and all other systems which put stabs
+     in sections, hopefully, since it would be silly to do things
+     differently from Solaris), and false for SunOS4 and other a.out
+     file formats.  */
+  block_address_function_relative =
+    ((0 == strncmp (bfd_get_target (sym_bfd), "elf", 3))
+     || (0 == strncmp (bfd_get_target (sym_bfd), "som", 3))
+     || (0 == strncmp (bfd_get_target (sym_bfd), "coff", 4))
+     || (0 == strncmp (bfd_get_target (sym_bfd), "pe", 2))
+     || (0 == strncmp (bfd_get_target (sym_bfd), "epoc-pe", 7))
+     || (0 == strncmp (bfd_get_target (sym_bfd), "nlm", 3)));
+
+  val = bfd_seek (sym_bfd, DBX_SYMTAB_OFFSET (objfile), SEEK_SET);
+  if (val < 0)
+    perror_with_name (objfile->name);
+
+  /* If we are reinitializing, or if we have never loaded syms yet, init */
+  if (mainline
+      || (objfile->global_psymbols.size == 0
+         &&  objfile->static_psymbols.size == 0))
+    init_psymbol_list (objfile, DBX_SYMCOUNT (objfile));
+
+  symbol_size = DBX_SYMBOL_SIZE (objfile);
+  symbol_table_offset = DBX_SYMTAB_OFFSET (objfile);
+
+  free_pending_blocks ();
+  back_to = make_cleanup (really_free_pendings, 0);
+
+  init_minimal_symbol_collection ();
+  make_cleanup_discard_minimal_symbols ();
+
+  /* Read stabs data from executable file and define symbols. */
+
+  read_dbx_symtab (objfile);
+
+  /* Add the dynamic symbols.  */
+
+  read_dbx_dynamic_symtab (objfile);
+
+  /* Install any minimal symbols that have been collected as the current
+     minimal symbols for this objfile. */
+
+  install_minimal_symbols (objfile);
+
+  do_cleanups (back_to);
+}
+
+/* Initialize anything that needs initializing when a completely new
+   symbol file is specified (not just adding some symbols from another
+   file, e.g. a shared library).  */
+
+static void
+dbx_new_init (struct objfile *ignore)
+{
+  stabsread_new_init ();
+  buildsym_new_init ();
+  init_header_files ();
+}
+
+
+/* dbx_symfile_init ()
+   is the dbx-specific initialization routine for reading symbols.
+   It is passed a struct objfile which contains, among other things,
+   the BFD for the file whose symbols are being read, and a slot for a pointer
+   to "private data" which we fill with goodies.
+
+   We read the string table into malloc'd space and stash a pointer to it.
+
+   Since BFD doesn't know how to read debug symbols in a format-independent
+   way (and may never do so...), we have to do it ourselves.  We will never
+   be called unless this is an a.out (or very similar) file. 
+   FIXME, there should be a cleaner peephole into the BFD environment here.  */
+
+#define DBX_STRINGTAB_SIZE_SIZE sizeof(long)   /* FIXME */
+
+static void
+dbx_symfile_init (struct objfile *objfile)
+{
+  int val;
+  bfd *sym_bfd = objfile->obfd;
+  char *name = bfd_get_filename (sym_bfd);
+  asection *text_sect;
+  unsigned char size_temp[DBX_STRINGTAB_SIZE_SIZE];
+
+  /* Allocate struct to keep track of the symfile */
+  objfile->sym_stab_info = (struct dbx_symfile_info *)
+    xmmalloc (objfile->md, sizeof (struct dbx_symfile_info));
+  memset ((PTR) objfile->sym_stab_info, 0, sizeof (struct dbx_symfile_info));
+
+  DBX_TEXT_SECTION (objfile) = bfd_get_section_by_name (sym_bfd, ".text");
+  DBX_DATA_SECTION (objfile) = bfd_get_section_by_name (sym_bfd, ".data");
+  DBX_BSS_SECTION (objfile) = bfd_get_section_by_name (sym_bfd, ".bss");
+
+  /* FIXME POKING INSIDE BFD DATA STRUCTURES */
+#define        STRING_TABLE_OFFSET     (sym_bfd->origin + obj_str_filepos (sym_bfd))
+#define        SYMBOL_TABLE_OFFSET     (sym_bfd->origin + obj_sym_filepos (sym_bfd))
+
+  /* FIXME POKING INSIDE BFD DATA STRUCTURES */
+
+  DBX_SYMFILE_INFO (objfile)->stab_section_info = NULL;
+
+  text_sect = bfd_get_section_by_name (sym_bfd, ".text");
+  if (!text_sect)
+    error ("Can't find .text section in symbol file");
+  DBX_TEXT_ADDR (objfile) = bfd_section_vma (sym_bfd, text_sect);
+  DBX_TEXT_SIZE (objfile) = bfd_section_size (sym_bfd, text_sect);
+
+  DBX_SYMBOL_SIZE (objfile) = obj_symbol_entry_size (sym_bfd);
+  DBX_SYMCOUNT (objfile) = bfd_get_symcount (sym_bfd);
+  DBX_SYMTAB_OFFSET (objfile) = SYMBOL_TABLE_OFFSET;
+
+  /* Read the string table and stash it away in the psymbol_obstack.  It is
+     only needed as long as we need to expand psymbols into full symbols,
+     so when we blow away the psymbol the string table goes away as well.
+     Note that gdb used to use the results of attempting to malloc the
+     string table, based on the size it read, as a form of sanity check
+     for botched byte swapping, on the theory that a byte swapped string
+     table size would be so totally bogus that the malloc would fail.  Now
+     that we put in on the psymbol_obstack, we can't do this since gdb gets
+     a fatal error (out of virtual memory) if the size is bogus.  We can
+     however at least check to see if the size is less than the size of
+     the size field itself, or larger than the size of the entire file.
+     Note that all valid string tables have a size greater than zero, since
+     the bytes used to hold the size are included in the count. */
+
+  if (STRING_TABLE_OFFSET == 0)
+    {
+      /* It appears that with the existing bfd code, STRING_TABLE_OFFSET
+         will never be zero, even when there is no string table.  This
+         would appear to be a bug in bfd. */
+      DBX_STRINGTAB_SIZE (objfile) = 0;
+      DBX_STRINGTAB (objfile) = NULL;
+    }
+  else
+    {
+      val = bfd_seek (sym_bfd, STRING_TABLE_OFFSET, SEEK_SET);
+      if (val < 0)
+       perror_with_name (name);
+
+      memset ((PTR) size_temp, 0, sizeof (size_temp));
+      val = bfd_bread ((PTR) size_temp, sizeof (size_temp), sym_bfd);
+      if (val < 0)
+       {
+         perror_with_name (name);
+       }
+      else if (val == 0)
+       {
+         /* With the existing bfd code, STRING_TABLE_OFFSET will be set to
+            EOF if there is no string table, and attempting to read the size
+            from EOF will read zero bytes. */
+         DBX_STRINGTAB_SIZE (objfile) = 0;
+         DBX_STRINGTAB (objfile) = NULL;
+       }
+      else
+       {
+         /* Read some data that would appear to be the string table size.
+            If there really is a string table, then it is probably the right
+            size.  Byteswap if necessary and validate the size.  Note that
+            the minimum is DBX_STRINGTAB_SIZE_SIZE.  If we just read some
+            random data that happened to be at STRING_TABLE_OFFSET, because
+            bfd can't tell us there is no string table, the sanity checks may
+            or may not catch this. */
+         DBX_STRINGTAB_SIZE (objfile) = bfd_h_get_32 (sym_bfd, size_temp);
+
+         if (DBX_STRINGTAB_SIZE (objfile) < sizeof (size_temp)
+             || DBX_STRINGTAB_SIZE (objfile) > bfd_get_size (sym_bfd))
+           error ("ridiculous string table size (%d bytes).",
+                  DBX_STRINGTAB_SIZE (objfile));
+
+         DBX_STRINGTAB (objfile) =
+           (char *) obstack_alloc (&objfile->psymbol_obstack,
+                                   DBX_STRINGTAB_SIZE (objfile));
+         OBJSTAT (objfile, sz_strtab += DBX_STRINGTAB_SIZE (objfile));
+
+         /* Now read in the string table in one big gulp.  */
+
+         val = bfd_seek (sym_bfd, STRING_TABLE_OFFSET, SEEK_SET);
+         if (val < 0)
+           perror_with_name (name);
+         val = bfd_bread (DBX_STRINGTAB (objfile),
+                          DBX_STRINGTAB_SIZE (objfile),
+                          sym_bfd);
+         if (val != DBX_STRINGTAB_SIZE (objfile))
+           perror_with_name (name);
+       }
+    }
+}
+
+/* Perform any local cleanups required when we are done with a particular
+   objfile.  I.E, we are in the process of discarding all symbol information
+   for an objfile, freeing up all memory held for it, and unlinking the
+   objfile struct from the global list of known objfiles. */
+
+static void
+dbx_symfile_finish (struct objfile *objfile)
+{
+  if (objfile->sym_stab_info != NULL)
+    {
+      if (HEADER_FILES (objfile) != NULL)
+       {
+         register int i = N_HEADER_FILES (objfile);
+         register struct header_file *hfiles = HEADER_FILES (objfile);
+
+         while (--i >= 0)
+           {
+             xfree (hfiles[i].name);
+             xfree (hfiles[i].vector);
+           }
+         xfree (hfiles);
+       }
+      xmfree (objfile->md, objfile->sym_stab_info);
+    }
+  free_header_files ();
+}
+\f
+
+/* Buffer for reading the symbol table entries.  */
+static struct external_nlist symbuf[4096];
+static int symbuf_idx;
+static int symbuf_end;
+
+/* cont_elem is used for continuing information in cfront.
+   It saves information about which types need to be fixed up and 
+   completed after all the stabs are read.  */
+struct cont_elem
+  {
+    /* sym and stabstring for continuing information in cfront */
+    struct symbol *sym;
+    char *stabs;
+    /* state dependencies (statics that must be preserved) */
+    int sym_idx;
+    int sym_end;
+    int symnum;
+    int (*func) (struct objfile *, struct symbol *, char *);
+    /* other state dependencies include:
+       (assumption is that these will not change since process_now FIXME!!)
+       stringtab_global
+       n_stabs
+       objfile
+       symfile_bfd */
+  };
+
+static struct cont_elem *cont_list = 0;
+static int cont_limit = 0;
+static int cont_count = 0;
+
+/* Arrange for function F to be called with arguments SYM and P later
+   in the stabs reading process.  */
+void
+process_later (struct symbol *sym, char *p,
+              int (*f) (struct objfile *, struct symbol *, char *))
+{
+
+  /* Allocate more space for the deferred list.  */
+  if (cont_count >= cont_limit - 1)
+    {
+      cont_limit += 32;                /* chunk size */
+
+      cont_list
+       = (struct cont_elem *) xrealloc (cont_list,
+                                        (cont_limit
+                                         * sizeof (struct cont_elem)));
+      if (!cont_list)
+       error ("Virtual memory exhausted\n");
+    }
+
+  /* Save state variables so we can process these stabs later.  */
+  cont_list[cont_count].sym_idx = symbuf_idx;
+  cont_list[cont_count].sym_end = symbuf_end;
+  cont_list[cont_count].symnum = symnum;
+  cont_list[cont_count].sym = sym;
+  cont_list[cont_count].stabs = p;
+  cont_list[cont_count].func = f;
+  cont_count++;
+}
+
+/* Call deferred funtions in CONT_LIST.  */
+
+static void
+process_now (struct objfile *objfile)
+{
+  int i;
+  int save_symbuf_idx;
+  int save_symbuf_end;
+  int save_symnum;
+  struct symbol *sym;
+  char *stabs;
+  int err;
+  int (*func) (struct objfile *, struct symbol *, char *);
+
+  /* Save the state of our caller, we'll want to restore it before
+     returning.  */
+  save_symbuf_idx = symbuf_idx;
+  save_symbuf_end = symbuf_end;
+  save_symnum = symnum;
+
+  /* Iterate over all the deferred stabs.  */
+  for (i = 0; i < cont_count; i++)
+    {
+      /* Restore the state for this deferred stab.  */
+      symbuf_idx = cont_list[i].sym_idx;
+      symbuf_end = cont_list[i].sym_end;
+      symnum = cont_list[i].symnum;
+      sym = cont_list[i].sym;
+      stabs = cont_list[i].stabs;
+      func = cont_list[i].func;
+
+      /* Call the function to handle this deferrd stab.  */
+      err = (*func) (objfile, sym, stabs);
+      if (err)
+       error ("Internal error: unable to resolve stab.\n");
+    }
+
+  /* Restore our caller's state.  */
+  symbuf_idx = save_symbuf_idx;
+  symbuf_end = save_symbuf_end;
+  symnum = save_symnum;
+  cont_count = 0;
+}
+
+
+/* Name of last function encountered.  Used in Solaris to approximate
+   object file boundaries.  */
+static char *last_function_name;
+
+/* The address in memory of the string table of the object file we are
+   reading (which might not be the "main" object file, but might be a
+   shared library or some other dynamically loaded thing).  This is
+   set by read_dbx_symtab when building psymtabs, and by
+   read_ofile_symtab when building symtabs, and is used only by
+   next_symbol_text.  FIXME: If that is true, we don't need it when
+   building psymtabs, right?  */
+static char *stringtab_global;
+
+/* These variables are used to control fill_symbuf when the stabs
+   symbols are not contiguous (as may be the case when a COFF file is
+   linked using --split-by-reloc).  */
+static struct stab_section_list *symbuf_sections;
+static unsigned int symbuf_left;
+static unsigned int symbuf_read;
+
+/* Refill the symbol table input buffer
+   and set the variables that control fetching entries from it.
+   Reports an error if no data available.
+   This function can read past the end of the symbol table
+   (into the string table) but this does no harm.  */
+
+static void
+fill_symbuf (bfd *sym_bfd)
+{
+  unsigned int count;
+  int nbytes;
+
+  if (symbuf_sections == NULL)
+    count = sizeof (symbuf);
+  else
+    {
+      if (symbuf_left <= 0)
+       {
+         file_ptr filepos = symbuf_sections->section->filepos;
+         if (bfd_seek (sym_bfd, filepos, SEEK_SET) != 0)
+           perror_with_name (bfd_get_filename (sym_bfd));
+         symbuf_left = bfd_section_size (sym_bfd, symbuf_sections->section);
+         symbol_table_offset = filepos - symbuf_read;
+         symbuf_sections = symbuf_sections->next;
+       }
+
+      count = symbuf_left;
+      if (count > sizeof (symbuf))
+       count = sizeof (symbuf);
+    }
+
+  nbytes = bfd_bread ((PTR) symbuf, count, sym_bfd);
+  if (nbytes < 0)
+    perror_with_name (bfd_get_filename (sym_bfd));
+  else if (nbytes == 0)
+    error ("Premature end of file reading symbol table");
+  symbuf_end = nbytes / symbol_size;
+  symbuf_idx = 0;
+  symbuf_left -= nbytes;
+  symbuf_read += nbytes;
+}
+
+#define INTERNALIZE_SYMBOL(intern, extern, abfd)                       \
+  {                                                                    \
+    (intern).n_type = bfd_h_get_8 (abfd, (extern)->e_type);            \
+    (intern).n_strx = bfd_h_get_32 (abfd, (extern)->e_strx);           \
+    (intern).n_desc = bfd_h_get_16 (abfd, (extern)->e_desc);           \
+    if (bfd_get_sign_extend_vma (abfd))                                        \
+      (intern).n_value = bfd_h_get_signed_32 (abfd, (extern)->e_value);        \
+    else                                                               \
+      (intern).n_value = bfd_h_get_32 (abfd, (extern)->e_value);       \
+  }
+
+/* Invariant: The symbol pointed to by symbuf_idx is the first one
+   that hasn't been swapped.  Swap the symbol at the same time
+   that symbuf_idx is incremented.  */
+
+/* dbx allows the text of a symbol name to be continued into the
+   next symbol name!  When such a continuation is encountered
+   (a \ at the end of the text of a name)
+   call this function to get the continuation.  */
+
+static char *
+dbx_next_symbol_text (struct objfile *objfile)
+{
+  struct internal_nlist nlist;
+
+  if (symbuf_idx == symbuf_end)
+    fill_symbuf (symfile_bfd);
+
+  symnum++;
+  INTERNALIZE_SYMBOL (nlist, &symbuf[symbuf_idx], symfile_bfd);
+  OBJSTAT (objfile, n_stabs++);
+
+  symbuf_idx++;
+
+  return nlist.n_strx + stringtab_global + file_string_table_offset;
+}
+\f
+/* Initialize the list of bincls to contain none and have some
+   allocated.  */
+
+static void
+init_bincl_list (int number, struct objfile *objfile)
+{
+  bincls_allocated = number;
+  next_bincl = bincl_list = (struct header_file_location *)
+    xmmalloc (objfile->md, bincls_allocated * sizeof (struct header_file_location));
+}
+
+/* Add a bincl to the list.  */
+
+static void
+add_bincl_to_list (struct partial_symtab *pst, char *name, int instance)
+{
+  if (next_bincl >= bincl_list + bincls_allocated)
+    {
+      int offset = next_bincl - bincl_list;
+      bincls_allocated *= 2;
+      bincl_list = (struct header_file_location *)
+       xmrealloc (pst->objfile->md, (char *) bincl_list,
+                  bincls_allocated * sizeof (struct header_file_location));
+      next_bincl = bincl_list + offset;
+    }
+  next_bincl->pst = pst;
+  next_bincl->instance = instance;
+  next_bincl++->name = name;
+}
+
+/* Given a name, value pair, find the corresponding
+   bincl in the list.  Return the partial symtab associated
+   with that header_file_location.  */
+
+static struct partial_symtab *
+find_corresponding_bincl_psymtab (char *name, int instance)
+{
+  struct header_file_location *bincl;
+
+  for (bincl = bincl_list; bincl < next_bincl; bincl++)
+    if (bincl->instance == instance
+       && STREQ (name, bincl->name))
+      return bincl->pst;
+
+  complain (&repeated_header_complaint, name, symnum);
+  return (struct partial_symtab *) 0;
+}
+
+/* Free the storage allocated for the bincl list.  */
+
+static void
+free_bincl_list (struct objfile *objfile)
+{
+  xmfree (objfile->md, (PTR) bincl_list);
+  bincls_allocated = 0;
+}
+
+static void
+do_free_bincl_list_cleanup (void *objfile)
+{
+  free_bincl_list (objfile);
+}
+
+static struct cleanup *
+make_cleanup_free_bincl_list (struct objfile *objfile)
+{
+  return make_cleanup (do_free_bincl_list_cleanup, objfile);
+}
+
+/* Set namestring based on nlist.  If the string table index is invalid, 
+   give a fake name, and print a single error message per symbol file read,
+   rather than abort the symbol reading or flood the user with messages.  */
+
+static char *
+set_namestring (struct objfile *objfile, struct internal_nlist nlist)
+{
+  char *namestring;
+
+  if (((unsigned) nlist.n_strx + file_string_table_offset) >=
+      DBX_STRINGTAB_SIZE (objfile))
+    {
+      complain (&string_table_offset_complaint, symnum);
+      namestring = "<bad string table offset>";
+    } 
+  else
+    namestring = nlist.n_strx + file_string_table_offset +
+      DBX_STRINGTAB (objfile);
+  return namestring;
+}
+
+/* Scan a SunOs dynamic symbol table for symbols of interest and
+   add them to the minimal symbol table.  */
+
+static void
+read_dbx_dynamic_symtab (struct objfile *objfile)
+{
+  bfd *abfd = objfile->obfd;
+  struct cleanup *back_to;
+  int counter;
+  long dynsym_size;
+  long dynsym_count;
+  asymbol **dynsyms;
+  asymbol **symptr;
+  arelent **relptr;
+  long dynrel_size;
+  long dynrel_count;
+  arelent **dynrels;
+  CORE_ADDR sym_value;
+  char *name;
+
+  /* Check that the symbol file has dynamic symbols that we know about.
+     bfd_arch_unknown can happen if we are reading a sun3 symbol file
+     on a sun4 host (and vice versa) and bfd is not configured
+     --with-target=all.  This would trigger an assertion in bfd/sunos.c,
+     so we ignore the dynamic symbols in this case.  */
+  if (bfd_get_flavour (abfd) != bfd_target_aout_flavour
+      || (bfd_get_file_flags (abfd) & DYNAMIC) == 0
+      || bfd_get_arch (abfd) == bfd_arch_unknown)
+    return;
+
+  dynsym_size = bfd_get_dynamic_symtab_upper_bound (abfd);
+  if (dynsym_size < 0)
+    return;
+
+  dynsyms = (asymbol **) xmalloc (dynsym_size);
+  back_to = make_cleanup (xfree, dynsyms);
+
+  dynsym_count = bfd_canonicalize_dynamic_symtab (abfd, dynsyms);
+  if (dynsym_count < 0)
+    {
+      do_cleanups (back_to);
+      return;
+    }
+
+  /* Enter dynamic symbols into the minimal symbol table
+     if this is a stripped executable.  */
+  if (bfd_get_symcount (abfd) <= 0)
+    {
+      symptr = dynsyms;
+      for (counter = 0; counter < dynsym_count; counter++, symptr++)
+       {
+         asymbol *sym = *symptr;
+         asection *sec;
+         int type;
+
+         sec = bfd_get_section (sym);
+
+         /* BFD symbols are section relative.  */
+         sym_value = sym->value + sec->vma;
+
+         if (bfd_get_section_flags (abfd, sec) & SEC_CODE)
+           {
+             sym_value += ANOFFSET (objfile->section_offsets, SECT_OFF_TEXT (objfile));
+             type = N_TEXT;
+           }
+         else if (bfd_get_section_flags (abfd, sec) & SEC_DATA)
+           {
+             sym_value += ANOFFSET (objfile->section_offsets, SECT_OFF_DATA (objfile));
+             type = N_DATA;
+           }
+         else if (bfd_get_section_flags (abfd, sec) & SEC_ALLOC)
+           {
+             sym_value += ANOFFSET (objfile->section_offsets, SECT_OFF_BSS (objfile));
+             type = N_BSS;
+           }
+         else
+           continue;
+
+         if (sym->flags & BSF_GLOBAL)
+           type |= N_EXT;
+
+         record_minimal_symbol ((char *) bfd_asymbol_name (sym), sym_value,
+                                type, objfile);
+       }
+    }
+
+  /* Symbols from shared libraries have a dynamic relocation entry
+     that points to the associated slot in the procedure linkage table.
+     We make a mininal symbol table entry with type mst_solib_trampoline
+     at the address in the procedure linkage table.  */
+  dynrel_size = bfd_get_dynamic_reloc_upper_bound (abfd);
+  if (dynrel_size < 0)
+    {
+      do_cleanups (back_to);
+      return;
+    }
+
+  dynrels = (arelent **) xmalloc (dynrel_size);
+  make_cleanup (xfree, dynrels);
+
+  dynrel_count = bfd_canonicalize_dynamic_reloc (abfd, dynrels, dynsyms);
+  if (dynrel_count < 0)
+    {
+      do_cleanups (back_to);
+      return;
+    }
+
+  for (counter = 0, relptr = dynrels;
+       counter < dynrel_count;
+       counter++, relptr++)
+    {
+      arelent *rel = *relptr;
+      CORE_ADDR address =
+      rel->address + ANOFFSET (objfile->section_offsets, SECT_OFF_DATA (objfile));
+
+      switch (bfd_get_arch (abfd))
+       {
+       case bfd_arch_sparc:
+         if (rel->howto->type != RELOC_JMP_SLOT)
+           continue;
+         break;
+       case bfd_arch_m68k:
+         /* `16' is the type BFD produces for a jump table relocation.  */
+         if (rel->howto->type != 16)
+           continue;
+
+         /* Adjust address in the jump table to point to
+            the start of the bsr instruction.  */
+         address -= 2;
+         break;
+       default:
+         continue;
+       }
+
+      name = (char *) bfd_asymbol_name (*rel->sym_ptr_ptr);
+      prim_record_minimal_symbol (name, address, mst_solib_trampoline,
+                                 objfile);
+    }
+
+  do_cleanups (back_to);
+}
+
+#ifdef SOFUN_ADDRESS_MAYBE_MISSING
+CORE_ADDR
+find_stab_function_addr (char *namestring, char *filename,
+                        struct objfile *objfile)
+{
+  struct minimal_symbol *msym;
+  char *p;
+  int n;
+
+  p = strchr (namestring, ':');
+  if (p == NULL)
+    p = namestring;
+  n = p - namestring;
+  p = alloca (n + 2);
+  strncpy (p, namestring, n);
+  p[n] = 0;
+
+  msym = lookup_minimal_symbol (p, filename, objfile);
+  if (msym == NULL)
+    {
+      /* Sun Fortran appends an underscore to the minimal symbol name,
+         try again with an appended underscore if the minimal symbol
+         was not found.  */
+      p[n] = '_';
+      p[n + 1] = 0;
+      msym = lookup_minimal_symbol (p, filename, objfile);
+    }
+
+  if (msym == NULL && filename != NULL)
+    {
+      /* Try again without the filename. */
+      p[n] = 0;
+      msym = lookup_minimal_symbol (p, NULL, objfile);
+    }
+  if (msym == NULL && filename != NULL)
+    {
+      /* And try again for Sun Fortran, but without the filename. */
+      p[n] = '_';
+      p[n + 1] = 0;
+      msym = lookup_minimal_symbol (p, NULL, objfile);
+    }
+
+  return msym == NULL ? 0 : SYMBOL_VALUE_ADDRESS (msym);
+}
+#endif /* SOFUN_ADDRESS_MAYBE_MISSING */
+
+/* Setup partial_symtab's describing each source file for which
+   debugging information is available. */
+
+static void
+read_dbx_symtab (struct objfile *objfile)
+{
+  register struct external_nlist *bufp = 0;    /* =0 avoids gcc -Wall glitch */
+  struct internal_nlist nlist;
+  CORE_ADDR text_addr;
+  int text_size;
+
+  register char *namestring;
+  int nsl;
+  int past_first_source_file = 0;
+  CORE_ADDR last_o_file_start = 0;
+  CORE_ADDR last_function_start = 0;
+  struct cleanup *back_to;
+  bfd *abfd;
+  int textlow_not_set;
+
+  /* Current partial symtab */
+  struct partial_symtab *pst;
+
+  /* List of current psymtab's include files */
+  char **psymtab_include_list;
+  int includes_allocated;
+  int includes_used;
+
+  /* Index within current psymtab dependency list */
+  struct partial_symtab **dependency_list;
+  int dependencies_used, dependencies_allocated;
+
+  text_addr = DBX_TEXT_ADDR (objfile);
+  text_size = DBX_TEXT_SIZE (objfile);
+
+  /* FIXME.  We probably want to change stringtab_global rather than add this
+     while processing every symbol entry.  FIXME.  */
+  file_string_table_offset = 0;
+  next_file_string_table_offset = 0;
+
+  stringtab_global = DBX_STRINGTAB (objfile);
+
+  pst = (struct partial_symtab *) 0;
+
+  includes_allocated = 30;
+  includes_used = 0;
+  psymtab_include_list = (char **) alloca (includes_allocated *
+                                          sizeof (char *));
+
+  dependencies_allocated = 30;
+  dependencies_used = 0;
+  dependency_list =
+    (struct partial_symtab **) alloca (dependencies_allocated *
+                                      sizeof (struct partial_symtab *));
+
+  /* Init bincl list */
+  init_bincl_list (20, objfile);
+  back_to = make_cleanup_free_bincl_list (objfile);
+
+  last_source_file = NULL;
+
+  lowest_text_address = (CORE_ADDR) -1;
+
+  symfile_bfd = objfile->obfd; /* For next_text_symbol */
+  abfd = objfile->obfd;
+  symbuf_end = symbuf_idx = 0;
+  next_symbol_text_func = dbx_next_symbol_text;
+  textlow_not_set = 1;
+  has_line_numbers = 0;
+
+  for (symnum = 0; symnum < DBX_SYMCOUNT (objfile); symnum++)
+    {
+      /* Get the symbol for this run and pull out some info */
+      QUIT;                    /* allow this to be interruptable */
+      if (symbuf_idx == symbuf_end)
+       fill_symbuf (abfd);
+      bufp = &symbuf[symbuf_idx++];
+
+      /*
+       * Special case to speed up readin.
+       */
+      if (bfd_h_get_8 (abfd, bufp->e_type) == N_SLINE)
+       {
+         has_line_numbers = 1;
+         continue;
+       }
+
+      INTERNALIZE_SYMBOL (nlist, bufp, abfd);
+      OBJSTAT (objfile, n_stabs++);
+
+      /* Ok.  There is a lot of code duplicated in the rest of this
+         switch statement (for efficiency reasons).  Since I don't
+         like duplicating code, I will do my penance here, and
+         describe the code which is duplicated:
+
+         *) The assignment to namestring.
+         *) The call to strchr.
+         *) The addition of a partial symbol the the two partial
+         symbol lists.  This last is a large section of code, so
+         I've imbedded it in the following macro.
+      */
+
+      switch (nlist.n_type)
+       {
+         static struct complaint function_outside_compilation_unit = {
+           "function `%s' appears to be defined outside of all compilation units", 0, 0
+         };
+         char *p;
+         /*
+          * Standard, external, non-debugger, symbols
+          */
+
+         case N_TEXT | N_EXT:
+         case N_NBTEXT | N_EXT:
+         nlist.n_value += ANOFFSET (objfile->section_offsets, SECT_OFF_TEXT (objfile));
+         goto record_it;
+
+         case N_DATA | N_EXT:
+         case N_NBDATA | N_EXT:
+         nlist.n_value += ANOFFSET (objfile->section_offsets, SECT_OFF_DATA (objfile));
+         goto record_it;
+
+         case N_BSS:
+         case N_BSS | N_EXT:
+         case N_NBBSS | N_EXT:
+         case N_SETV | N_EXT:          /* FIXME, is this in BSS? */
+         nlist.n_value += ANOFFSET (objfile->section_offsets, SECT_OFF_BSS (objfile));
+         goto record_it;
+
+         case N_ABS | N_EXT:
+         record_it:
+         namestring = set_namestring (objfile, nlist);
+
+         bss_ext_symbol:
+         record_minimal_symbol (namestring, nlist.n_value,
+                                nlist.n_type, objfile);        /* Always */
+         continue;
+
+         /* Standard, local, non-debugger, symbols */
+
+         case N_NBTEXT:
+
+         /* We need to be able to deal with both N_FN or N_TEXT,
+            because we have no way of knowing whether the sys-supplied ld
+            or GNU ld was used to make the executable.  Sequents throw
+            in another wrinkle -- they renumbered N_FN.  */
+
+         case N_FN:
+         case N_FN_SEQ:
+         case N_TEXT:
+         nlist.n_value += ANOFFSET (objfile->section_offsets, SECT_OFF_TEXT (objfile));
+         namestring = set_namestring (objfile, nlist);
+
+         if ((namestring[0] == '-' && namestring[1] == 'l')
+             || (namestring[(nsl = strlen (namestring)) - 1] == 'o'
+                 && namestring[nsl - 2] == '.'))
+         {
+           if (objfile->ei.entry_point < nlist.n_value &&
+               objfile->ei.entry_point >= last_o_file_start)
+             {
+               objfile->ei.entry_file_lowpc = last_o_file_start;
+               objfile->ei.entry_file_highpc = nlist.n_value;
+             }
+           if (past_first_source_file && pst
+               /* The gould NP1 uses low values for .o and -l symbols
+                  which are not the address.  */
+               && nlist.n_value >= pst->textlow)
+             {
+               end_psymtab (pst, psymtab_include_list, includes_used,
+                            symnum * symbol_size,
+                            nlist.n_value > pst->texthigh
+                            ? nlist.n_value : pst->texthigh,
+                            dependency_list, dependencies_used, textlow_not_set);
+               pst = (struct partial_symtab *) 0;
+               includes_used = 0;
+               dependencies_used = 0;
+             }
+           else
+             past_first_source_file = 1;
+           last_o_file_start = nlist.n_value;
+         }
+         else
+         goto record_it;
+         continue;
+
+         case N_DATA:
+         nlist.n_value += ANOFFSET (objfile->section_offsets, SECT_OFF_DATA (objfile));
+         goto record_it;
+
+         case N_UNDF | N_EXT:
+         if (nlist.n_value != 0)
+         {
+           /* This is a "Fortran COMMON" symbol.  See if the target
+              environment knows where it has been relocated to.  */
+
+           CORE_ADDR reladdr;
+
+           namestring = set_namestring (objfile, nlist);
+           if (target_lookup_symbol (namestring, &reladdr))
+             {
+               continue;               /* Error in lookup; ignore symbol for now.  */
+             }
+           nlist.n_type ^= (N_BSS ^ N_UNDF);   /* Define it as a bss-symbol */
+           nlist.n_value = reladdr;
+           goto bss_ext_symbol;
+         }
+         continue;                     /* Just undefined, not COMMON */
+
+         case N_UNDF:
+         if (processing_acc_compilation && nlist.n_strx == 1)
+         {
+           /* Deal with relative offsets in the string table
+              used in ELF+STAB under Solaris.  If we want to use the
+              n_strx field, which contains the name of the file,
+              we must adjust file_string_table_offset *before* calling
+              set_namestring().  */
+           past_first_source_file = 1;
+           file_string_table_offset = next_file_string_table_offset;
+           next_file_string_table_offset =
+             file_string_table_offset + nlist.n_value;
+           if (next_file_string_table_offset < file_string_table_offset)
+             error ("string table offset backs up at %d", symnum);
+           /* FIXME -- replace error() with complaint.  */
+           continue;
+         }
+         continue;
+
+         /* Lots of symbol types we can just ignore.  */
+
+         case N_ABS:
+         case N_NBDATA:
+         case N_NBBSS:
+         continue;
+
+         /* Keep going . . . */
+
+         /*
+          * Special symbol types for GNU
+          */
+         case N_INDR:
+         case N_INDR | N_EXT:
+         case N_SETA:
+         case N_SETA | N_EXT:
+         case N_SETT:
+         case N_SETT | N_EXT:
+         case N_SETD:
+         case N_SETD | N_EXT:
+         case N_SETB:
+         case N_SETB | N_EXT:
+         case N_SETV:
+         continue;
+
+         /*
+          * Debugger symbols
+          */
+
+         case N_SO:
+         {
+           CORE_ADDR valu;
+           static int prev_so_symnum = -10;
+           static int first_so_symnum;
+           char *p;
+           int prev_textlow_not_set;
+
+           valu = nlist.n_value + ANOFFSET (objfile->section_offsets, SECT_OFF_TEXT (objfile));
+
+           prev_textlow_not_set = textlow_not_set;
+
+#ifdef SOFUN_ADDRESS_MAYBE_MISSING
+           /* A zero value is probably an indication for the SunPRO 3.0
+              compiler. end_psymtab explicitly tests for zero, so
+              don't relocate it.  */
+
+           if (nlist.n_value == 0)
+             {
+               textlow_not_set = 1;
+               valu = 0;
+             }
+           else
+             textlow_not_set = 0;
+#else
+           textlow_not_set = 0;
+#endif
+           past_first_source_file = 1;
+
+           if (prev_so_symnum != symnum - 1)
+             {                 /* Here if prev stab wasn't N_SO */
+               first_so_symnum = symnum;
+
+               if (pst)
+                 {
+                   end_psymtab (pst, psymtab_include_list, includes_used,
+                                symnum * symbol_size,
+                                valu > pst->texthigh ? valu : pst->texthigh,
+                                dependency_list, dependencies_used,
+                                prev_textlow_not_set);
+                   pst = (struct partial_symtab *) 0;
+                   includes_used = 0;
+                   dependencies_used = 0;
+                 }
+             }
+
+           prev_so_symnum = symnum;
+
+           /* End the current partial symtab and start a new one */
+
+           namestring = set_namestring (objfile, nlist);
+
+           /* Null name means end of .o file.  Don't start a new one. */
+           if (*namestring == '\000')
+             continue;
+
+           /* Some compilers (including gcc) emit a pair of initial N_SOs.
+              The first one is a directory name; the second the file name.
+              If pst exists, is empty, and has a filename ending in '/',
+              we assume the previous N_SO was a directory name. */
+
+           p = strrchr (namestring, '/');
+           if (p && *(p + 1) == '\000')
+             continue;         /* Simply ignore directory name SOs */
+
+           /* Some other compilers (C++ ones in particular) emit useless
+              SOs for non-existant .c files.  We ignore all subsequent SOs that
+              immediately follow the first.  */
+
+           if (!pst)
+             pst = start_psymtab (objfile,
+                                  namestring, valu,
+                                  first_so_symnum * symbol_size,
+                                  objfile->global_psymbols.next,
+                                  objfile->static_psymbols.next);
+           continue;
+         }
+
+         case N_BINCL:
+         {
+           enum language tmp_language;
+           /* Add this bincl to the bincl_list for future EXCLs.  No
+              need to save the string; it'll be around until
+              read_dbx_symtab function returns */
+
+           namestring = set_namestring (objfile, nlist);
+           tmp_language = deduce_language_from_filename (namestring);
+
+           /* Only change the psymtab's language if we've learned
+              something useful (eg. tmp_language is not language_unknown).
+              In addition, to match what start_subfile does, never change
+              from C++ to C.  */
+           if (tmp_language != language_unknown
+               && (tmp_language != language_c
+                   || psymtab_language != language_cplus))
+           psymtab_language = tmp_language;
+
+           if (pst == NULL)
+           {
+             /* FIXME: we should not get here without a PST to work on.
+                Attempt to recover.  */
+             complain (&unclaimed_bincl_complaint, namestring, symnum);
+             continue;
+           }
+           add_bincl_to_list (pst, namestring, nlist.n_value);
+
+           /* Mark down an include file in the current psymtab */
+
+           goto record_include_file;
+         }
+
+         case N_SOL:
+         {
+           enum language tmp_language;
+           /* Mark down an include file in the current psymtab */
+
+           namestring = set_namestring (objfile, nlist);
+           tmp_language = deduce_language_from_filename (namestring);
+
+           /* Only change the psymtab's language if we've learned
+              something useful (eg. tmp_language is not language_unknown).
+              In addition, to match what start_subfile does, never change
+              from C++ to C.  */
+           if (tmp_language != language_unknown
+               && (tmp_language != language_c
+                   || psymtab_language != language_cplus))
+           psymtab_language = tmp_language;
+
+           /* In C++, one may expect the same filename to come round many
+              times, when code is coming alternately from the main file
+              and from inline functions in other files. So I check to see
+              if this is a file we've seen before -- either the main
+              source file, or a previously included file.
+
+              This seems to be a lot of time to be spending on N_SOL, but
+              things like "break c-exp.y:435" need to work (I
+              suppose the psymtab_include_list could be hashed or put
+              in a binary tree, if profiling shows this is a major hog).  */
+           if (pst && STREQ (namestring, pst->filename))
+           continue;
+           {
+             register int i;
+             for (i = 0; i < includes_used; i++)
+               if (STREQ (namestring, psymtab_include_list[i]))
+                 {
+                   i = -1;
+                   break;
+                 }
+             if (i == -1)
+               continue;
+           }
+
+           record_include_file:
+
+           psymtab_include_list[includes_used++] = namestring;
+           if (includes_used >= includes_allocated)
+           {
+             char **orig = psymtab_include_list;
+
+             psymtab_include_list = (char **)
+               alloca ((includes_allocated *= 2) *
+                       sizeof (char *));
+             memcpy ((PTR) psymtab_include_list, (PTR) orig,
+                     includes_used * sizeof (char *));
+           }
+           continue;
+         }
+         case N_LSYM:                  /* Typedef or automatic variable. */
+         case N_STSYM:         /* Data seg var -- static  */
+         case N_LCSYM:         /* BSS      "  */
+         case N_ROSYM:         /* Read-only data seg var -- static.  */
+         case N_NBSTS:         /* Gould nobase.  */
+         case N_NBLCS:         /* symbols.  */
+         case N_FUN:
+         case N_GSYM:                  /* Global (extern) variable; can be
+                                          data or bss (sigh FIXME).  */
+
+         /* Following may probably be ignored; I'll leave them here
+            for now (until I do Pascal and Modula 2 extensions).  */
+
+         case N_PC:                    /* I may or may not need this; I
+                                          suspect not.  */
+         case N_M2C:                   /* I suspect that I can ignore this here. */
+         case N_SCOPE:         /* Same.   */
+
+         namestring = set_namestring (objfile, nlist);
+
+         /* See if this is an end of function stab.  */
+         if (pst && nlist.n_type == N_FUN && *namestring == '\000')
+         {
+           CORE_ADDR valu;
+
+           /* It's value is the size (in bytes) of the function for
+              function relative stabs, or the address of the function's
+              end for old style stabs.  */
+           valu = nlist.n_value + last_function_start;
+           if (pst->texthigh == 0 || valu > pst->texthigh)
+             pst->texthigh = valu;
+           break;
+         }
+
+         p = (char *) strchr (namestring, ':');
+         if (!p)
+         continue;                     /* Not a debugging symbol.   */
+
+
+
+         /* Main processing section for debugging symbols which
+            the initial read through the symbol tables needs to worry
+            about.  If we reach this point, the symbol which we are
+            considering is definitely one we are interested in.
+            p must also contain the (valid) index into the namestring
+            which indicates the debugging type symbol.  */
+
+         switch (p[1])
+         {
+         case 'S':
+           nlist.n_value += ANOFFSET (objfile->section_offsets, SECT_OFF_DATA (objfile));
+#ifdef STATIC_TRANSFORM_NAME
+           namestring = STATIC_TRANSFORM_NAME (namestring);
+#endif
+           add_psymbol_to_list (namestring, p - namestring,
+                                VAR_NAMESPACE, LOC_STATIC,
+                                &objfile->static_psymbols,
+                                0, nlist.n_value,
+                                psymtab_language, objfile);
+           continue;
+         case 'G':
+           nlist.n_value += ANOFFSET (objfile->section_offsets, SECT_OFF_DATA (objfile));
+           /* The addresses in these entries are reported to be
+              wrong.  See the code that reads 'G's for symtabs. */
+           add_psymbol_to_list (namestring, p - namestring,
+                                VAR_NAMESPACE, LOC_STATIC,
+                                &objfile->global_psymbols,
+                                0, nlist.n_value,
+                                psymtab_language, objfile);
+           continue;
+
+         case 'T':
+           /* When a 'T' entry is defining an anonymous enum, it
+              may have a name which is the empty string, or a
+              single space.  Since they're not really defining a
+              symbol, those shouldn't go in the partial symbol
+              table.  We do pick up the elements of such enums at
+              'check_enum:', below.  */
+           if (p >= namestring + 2
+               || (p == namestring + 1
+                   && namestring[0] != ' '))
+             {
+               add_psymbol_to_list (namestring, p - namestring,
+                                    STRUCT_NAMESPACE, LOC_TYPEDEF,
+                                    &objfile->static_psymbols,
+                                    nlist.n_value, 0,
+                                    psymtab_language, objfile);
+               if (p[2] == 't')
+                 {
+                   /* Also a typedef with the same name.  */
+                   add_psymbol_to_list (namestring, p - namestring,
+                                        VAR_NAMESPACE, LOC_TYPEDEF,
+                                        &objfile->static_psymbols,
+                                        nlist.n_value, 0,
+                                        psymtab_language, objfile);
+                   p += 1;
+                 }
+               /* The semantics of C++ state that "struct foo { ... }"
+                  also defines a typedef for "foo".  Unfortuantely, cfront
+                  never makes the typedef when translating from C++ to C.
+                  We make the typedef here so that "ptype foo" works as
+                  expected for cfront translated code.  */
+               else if (psymtab_language == language_cplus)
+                 {
+                   /* Also a typedef with the same name.  */
+                   add_psymbol_to_list (namestring, p - namestring,
+                                        VAR_NAMESPACE, LOC_TYPEDEF,
+                                        &objfile->static_psymbols,
+                                        nlist.n_value, 0,
+                                        psymtab_language, objfile);
+                 }
+             }
+           goto check_enum;
+         case 't':
+           if (p != namestring)        /* a name is there, not just :T... */
+             {
+               add_psymbol_to_list (namestring, p - namestring,
+                                    VAR_NAMESPACE, LOC_TYPEDEF,
+                                    &objfile->static_psymbols,
+                                    nlist.n_value, 0,
+                                    psymtab_language, objfile);
+             }
+         check_enum:
+           /* If this is an enumerated type, we need to
+              add all the enum constants to the partial symbol
+              table.  This does not cover enums without names, e.g.
+              "enum {a, b} c;" in C, but fortunately those are
+              rare.  There is no way for GDB to find those from the
+              enum type without spending too much time on it.  Thus
+              to solve this problem, the compiler needs to put out the
+              enum in a nameless type.  GCC2 does this.  */
+
+           /* We are looking for something of the form
+              <name> ":" ("t" | "T") [<number> "="] "e"
+              {<constant> ":" <value> ","} ";".  */
+
+           /* Skip over the colon and the 't' or 'T'.  */
+           p += 2;
+           /* This type may be given a number.  Also, numbers can come
+              in pairs like (0,26).  Skip over it.  */
+           while ((*p >= '0' && *p <= '9')
+                  || *p == '(' || *p == ',' || *p == ')'
+                  || *p == '=')
+             p++;
+
+           if (*p++ == 'e')
+             {
+               /* The aix4 compiler emits extra crud before the members.  */
+               if (*p == '-')
+                 {
+                   /* Skip over the type (?).  */
+                   while (*p != ':')
+                     p++;
+
+                   /* Skip over the colon.  */
+                   p++;
+                 }
+
+               /* We have found an enumerated type.  */
+               /* According to comments in read_enum_type
+                  a comma could end it instead of a semicolon.
+                  I don't know where that happens.
+                  Accept either.  */
+               while (*p && *p != ';' && *p != ',')
+                 {
+                   char *q;
+
+                   /* Check for and handle cretinous dbx symbol name
+                      continuation!  */
+                   if (*p == '\\' || (*p == '?' && p[1] == '\0'))
+                     p = next_symbol_text (objfile);
+
+                   /* Point to the character after the name
+                      of the enum constant.  */
+                   for (q = p; *q && *q != ':'; q++)
+                     ;
+                   /* Note that the value doesn't matter for
+                      enum constants in psymtabs, just in symtabs.  */
+                   add_psymbol_to_list (p, q - p,
+                                        VAR_NAMESPACE, LOC_CONST,
+                                        &objfile->static_psymbols, 0,
+                                        0, psymtab_language, objfile);
+                   /* Point past the name.  */
+                   p = q;
+                   /* Skip over the value.  */
+                   while (*p && *p != ',')
+                     p++;
+                   /* Advance past the comma.  */
+                   if (*p)
+                     p++;
+                 }
+             }
+           continue;
+         case 'c':
+           /* Constant, e.g. from "const" in Pascal.  */
+           add_psymbol_to_list (namestring, p - namestring,
+                                VAR_NAMESPACE, LOC_CONST,
+                                &objfile->static_psymbols, nlist.n_value,
+                                0, psymtab_language, objfile);
+           continue;
+
+         case 'f':
+           if (! pst)
+             {
+               int name_len = p - namestring;
+               char *name = xmalloc (name_len + 1);
+               memcpy (name, namestring, name_len);
+               name[name_len] = '\0';
+               complain (&function_outside_compilation_unit, name);
+               xfree (name);
+             }
+           nlist.n_value += ANOFFSET (objfile->section_offsets, SECT_OFF_TEXT (objfile));
+           /* Kludges for ELF/STABS with Sun ACC */
+           last_function_name = namestring;
+#ifdef SOFUN_ADDRESS_MAYBE_MISSING
+           /* Do not fix textlow==0 for .o or NLM files, as 0 is a legit
+              value for the bottom of the text seg in those cases. */
+           if (nlist.n_value == ANOFFSET (objfile->section_offsets, 
+                                          SECT_OFF_TEXT (objfile)))
+             {
+               CORE_ADDR minsym_valu = 
+                 find_stab_function_addr (namestring, pst->filename, objfile);
+               /* find_stab_function_addr will return 0 if the minimal
+                  symbol wasn't found.  (Unfortunately, this might also
+                  be a valid address.)  Anyway, if it *does* return 0,
+                  it is likely that the value was set correctly to begin
+                  with... */
+               if (minsym_valu != 0)
+                 nlist.n_value = minsym_valu;
+             }
+           if (pst && textlow_not_set)
+             {
+               pst->textlow = nlist.n_value;
+               textlow_not_set = 0;
+             }
+#endif
+           /* End kludge.  */
+
+           /* Keep track of the start of the last function so we
+              can handle end of function symbols.  */
+           last_function_start = nlist.n_value;
+
+           /* In reordered executables this function may lie outside
+              the bounds created by N_SO symbols.  If that's the case
+              use the address of this function as the low bound for
+              the partial symbol table.  */
+           if (pst
+               && (textlow_not_set
+                   || (nlist.n_value < pst->textlow
+                       && (nlist.n_value
+                           != ANOFFSET (objfile->section_offsets,
+                                        SECT_OFF_TEXT (objfile))))))
+             {
+               pst->textlow = nlist.n_value;
+               textlow_not_set = 0;
+             }
+           add_psymbol_to_list (namestring, p - namestring,
+                                VAR_NAMESPACE, LOC_BLOCK,
+                                &objfile->static_psymbols,
+                                0, nlist.n_value,
+                                psymtab_language, objfile);
+           continue;
+
+           /* Global functions were ignored here, but now they
+              are put into the global psymtab like one would expect.
+              They're also in the minimal symbol table.  */
+         case 'F':
+           if (! pst)
+             {
+               int name_len = p - namestring;
+               char *name = xmalloc (name_len + 1);
+               memcpy (name, namestring, name_len);
+               name[name_len] = '\0';
+               complain (&function_outside_compilation_unit, name);
+               xfree (name);
+             }
+           nlist.n_value += ANOFFSET (objfile->section_offsets, SECT_OFF_TEXT (objfile));
+           /* Kludges for ELF/STABS with Sun ACC */
+           last_function_name = namestring;
+#ifdef SOFUN_ADDRESS_MAYBE_MISSING
+           /* Do not fix textlow==0 for .o or NLM files, as 0 is a legit
+              value for the bottom of the text seg in those cases. */
+           if (nlist.n_value == ANOFFSET (objfile->section_offsets, 
+                                          SECT_OFF_TEXT (objfile)))
+             {
+               CORE_ADDR minsym_valu = 
+                 find_stab_function_addr (namestring, pst->filename, objfile);
+               /* find_stab_function_addr will return 0 if the minimal
+                  symbol wasn't found.  (Unfortunately, this might also
+                  be a valid address.)  Anyway, if it *does* return 0,
+                  it is likely that the value was set correctly to begin
+                  with... */
+               if (minsym_valu != 0)
+                 nlist.n_value = minsym_valu;
+             }
+           if (pst && textlow_not_set)
+             {
+               pst->textlow = nlist.n_value;
+               textlow_not_set = 0;
+             }
+#endif
+           /* End kludge.  */
+
+           /* Keep track of the start of the last function so we
+              can handle end of function symbols.  */
+           last_function_start = nlist.n_value;
+
+           /* In reordered executables this function may lie outside
+              the bounds created by N_SO symbols.  If that's the case
+              use the address of this function as the low bound for
+              the partial symbol table.  */
+           if (pst
+               && (textlow_not_set
+                   || (nlist.n_value < pst->textlow
+                       && (nlist.n_value
+                           != ANOFFSET (objfile->section_offsets,
+                                        SECT_OFF_TEXT (objfile))))))
+             {
+               pst->textlow = nlist.n_value;
+               textlow_not_set = 0;
+             }
+           add_psymbol_to_list (namestring, p - namestring,
+                                VAR_NAMESPACE, LOC_BLOCK,
+                                &objfile->global_psymbols,
+                                0, nlist.n_value,
+                                psymtab_language, objfile);
+           continue;
+
+           /* Two things show up here (hopefully); static symbols of
+              local scope (static used inside braces) or extensions
+              of structure symbols.  We can ignore both.  */
+         case 'V':
+         case '(':
+         case '0':
+         case '1':
+         case '2':
+         case '3':
+         case '4':
+         case '5':
+         case '6':
+         case '7':
+         case '8':
+         case '9':
+         case '-':
+         case '#':             /* for symbol identification (used in live ranges) */
+           /* added to support cfront stabs strings */
+         case 'Z':             /* for definition continuations */
+         case 'P':             /* for prototypes */
+           continue;
+
+         case ':':
+           /* It is a C++ nested symbol.  We don't need to record it
+              (I don't think); if we try to look up foo::bar::baz,
+              then symbols for the symtab containing foo should get
+              read in, I think.  */
+           /* Someone says sun cc puts out symbols like
+              /foo/baz/maclib::/usr/local/bin/maclib,
+              which would get here with a symbol type of ':'.  */
+           continue;
+
+         default:
+           /* Unexpected symbol descriptor.  The second and subsequent stabs
+              of a continued stab can show up here.  The question is
+              whether they ever can mimic a normal stab--it would be
+              nice if not, since we certainly don't want to spend the
+              time searching to the end of every string looking for
+              a backslash.  */
+
+           complain (&unknown_symchar_complaint, p[1]);
+
+           /* Ignore it; perhaps it is an extension that we don't
+              know about.  */
+           continue;
+         }
+
+         case N_EXCL:
+
+         namestring = set_namestring (objfile, nlist);
+
+         /* Find the corresponding bincl and mark that psymtab on the
+            psymtab dependency list */
+         {
+           struct partial_symtab *needed_pst =
+             find_corresponding_bincl_psymtab (namestring, nlist.n_value);
+
+           /* If this include file was defined earlier in this file,
+              leave it alone.  */
+           if (needed_pst == pst)
+             continue;
+
+           if (needed_pst)
+             {
+               int i;
+               int found = 0;
+
+               for (i = 0; i < dependencies_used; i++)
+                 if (dependency_list[i] == needed_pst)
+                   {
+                     found = 1;
+                     break;
+                   }
+
+               /* If it's already in the list, skip the rest.  */
+               if (found)
+                 continue;
+
+               dependency_list[dependencies_used++] = needed_pst;
+               if (dependencies_used >= dependencies_allocated)
+                 {
+                   struct partial_symtab **orig = dependency_list;
+                   dependency_list =
+                     (struct partial_symtab **)
+                     alloca ((dependencies_allocated *= 2)
+                             * sizeof (struct partial_symtab *));
+                   memcpy ((PTR) dependency_list, (PTR) orig,
+                           (dependencies_used
+                            * sizeof (struct partial_symtab *)));
+#ifdef DEBUG_INFO
+                   fprintf_unfiltered (gdb_stderr, "Had to reallocate dependency list.\n");
+                   fprintf_unfiltered (gdb_stderr, "New dependencies allocated: %d\n",
+                                       dependencies_allocated);
+#endif
+                 }
+             }
+         }
+         continue;
+
+         case N_ENDM:
+#ifdef SOFUN_ADDRESS_MAYBE_MISSING
+         /* Solaris 2 end of module, finish current partial symbol table.
+            end_psymtab will set pst->texthigh to the proper value, which
+            is necessary if a module compiled without debugging info
+            follows this module.  */
+         if (pst)
+         {
+           end_psymtab (pst, psymtab_include_list, includes_used,
+                        symnum * symbol_size,
+                        (CORE_ADDR) 0,
+                        dependency_list, dependencies_used, textlow_not_set);
+           pst = (struct partial_symtab *) 0;
+           includes_used = 0;
+           dependencies_used = 0;
+         }
+#endif
+         continue;
+
+         case N_RBRAC:
+#ifdef HANDLE_RBRAC
+         HANDLE_RBRAC (nlist.n_value);
+         continue;
+#endif
+         case N_EINCL:
+         case N_DSLINE:
+         case N_BSLINE:
+         case N_SSYM:                  /* Claim: Structure or union element.
+                                          Hopefully, I can ignore this.  */
+         case N_ENTRY:         /* Alternate entry point; can ignore. */
+         case N_MAIN:                  /* Can definitely ignore this.   */
+         case N_CATCH:         /* These are GNU C++ extensions */
+         case N_EHDECL:                /* that can safely be ignored here. */
+         case N_LENG:
+         case N_BCOMM:
+         case N_ECOMM:
+         case N_ECOML:
+         case N_FNAME:
+         case N_SLINE:
+         case N_RSYM:
+         case N_PSYM:
+         case N_LBRAC:
+         case N_NSYMS:         /* Ultrix 4.0: symbol count */
+         case N_DEFD:                  /* GNU Modula-2 */
+         case N_ALIAS:         /* SunPro F77: alias name, ignore for now.  */
+
+         case N_OBJ:                   /* useless types from Solaris */
+         case N_OPT:
+         /* These symbols aren't interesting; don't worry about them */
+
+         continue;
+
+         default:
+         /* If we haven't found it yet, ignore it.  It's probably some
+            new type we don't know about yet.  */
+         complain (&unknown_symtype_complaint,
+                   local_hex_string (nlist.n_type));
+         continue;
+       }
+    }
+
+  /* If there's stuff to be cleaned up, clean it up.  */
+  if (DBX_SYMCOUNT (objfile) > 0       /* We have some syms */
+      /*FIXME, does this have a bug at start address 0? */
+      && last_o_file_start
+      && objfile->ei.entry_point < nlist.n_value
+      && objfile->ei.entry_point >= last_o_file_start)
+    {
+      objfile->ei.entry_file_lowpc = last_o_file_start;
+      objfile->ei.entry_file_highpc = nlist.n_value;
+    }
+
+  if (pst)
+    {
+      /* Don't set pst->texthigh lower than it already is.  */
+      CORE_ADDR text_end =
+       (lowest_text_address == (CORE_ADDR) -1
+        ? (text_addr + ANOFFSET (objfile->section_offsets, SECT_OFF_TEXT (objfile)))
+        : lowest_text_address)
+       + text_size;
+
+      end_psymtab (pst, psymtab_include_list, includes_used,
+                  symnum * symbol_size,
+                  text_end > pst->texthigh ? text_end : pst->texthigh,
+                  dependency_list, dependencies_used, textlow_not_set);
+    }
+
+  do_cleanups (back_to);
+}
+
+/* Allocate and partially fill a partial symtab.  It will be
+   completely filled at the end of the symbol list.
+
+   SYMFILE_NAME is the name of the symbol-file we are reading from, and ADDR
+   is the address relative to which its symbols are (incremental) or 0
+   (normal). */
+
+
+static struct partial_symtab *
+start_psymtab (struct objfile *objfile, char *filename, CORE_ADDR textlow,
+              int ldsymoff, struct partial_symbol **global_syms,
+              struct partial_symbol **static_syms)
+{
+  struct partial_symtab *result =
+  start_psymtab_common (objfile, objfile->section_offsets,
+                       filename, textlow, global_syms, static_syms);
+
+  result->read_symtab_private = (char *)
+    obstack_alloc (&objfile->psymbol_obstack, sizeof (struct symloc));
+  LDSYMOFF (result) = ldsymoff;
+  result->read_symtab = dbx_psymtab_to_symtab;
+  SYMBOL_SIZE (result) = symbol_size;
+  SYMBOL_OFFSET (result) = symbol_table_offset;
+  STRING_OFFSET (result) = string_table_offset;
+  FILE_STRING_OFFSET (result) = file_string_table_offset;
+
+  /* If we're handling an ELF file, drag some section-relocation info
+     for this source file out of the ELF symbol table, to compensate for
+     Sun brain death.  This replaces the section_offsets in this psymtab,
+     if successful.  */
+  elfstab_offset_sections (objfile, result);
+
+  /* Deduce the source language from the filename for this psymtab. */
+  psymtab_language = deduce_language_from_filename (filename);
+
+  return result;
+}
+
+/* Close off the current usage of PST.  
+   Returns PST or NULL if the partial symtab was empty and thrown away.
+
+   FIXME:  List variables and peculiarities of same.  */
+
+struct partial_symtab *
+end_psymtab (struct partial_symtab *pst, char **include_list, int num_includes,
+            int capping_symbol_offset, CORE_ADDR capping_text,
+            struct partial_symtab **dependency_list, int number_dependencies,
+            int textlow_not_set)
+{
+  int i;
+  struct objfile *objfile = pst->objfile;
+
+  if (capping_symbol_offset != -1)
+    LDSYMLEN (pst) = capping_symbol_offset - LDSYMOFF (pst);
+  pst->texthigh = capping_text;
+
+#ifdef SOFUN_ADDRESS_MAYBE_MISSING
+  /* Under Solaris, the N_SO symbols always have a value of 0,
+     instead of the usual address of the .o file.  Therefore,
+     we have to do some tricks to fill in texthigh and textlow.
+     The first trick is: if we see a static
+     or global function, and the textlow for the current pst
+     is not set (ie: textlow_not_set), then we use that function's
+     address for the textlow of the pst.  */
+
+  /* Now, to fill in texthigh, we remember the last function seen
+     in the .o file.  Also, there's a hack in
+     bfd/elf.c and gdb/elfread.c to pass the ELF st_size field
+     to here via the misc_info field.  Therefore, we can fill in
+     a reliable texthigh by taking the address plus size of the
+     last function in the file.  */
+
+  if (pst->texthigh == 0 && last_function_name)
+    {
+      char *p;
+      int n;
+      struct minimal_symbol *minsym;
+
+      p = strchr (last_function_name, ':');
+      if (p == NULL)
+       p = last_function_name;
+      n = p - last_function_name;
+      p = alloca (n + 2);
+      strncpy (p, last_function_name, n);
+      p[n] = 0;
+
+      minsym = lookup_minimal_symbol (p, pst->filename, objfile);
+      if (minsym == NULL)
+       {
+         /* Sun Fortran appends an underscore to the minimal symbol name,
+            try again with an appended underscore if the minimal symbol
+            was not found.  */
+         p[n] = '_';
+         p[n + 1] = 0;
+         minsym = lookup_minimal_symbol (p, pst->filename, objfile);
+       }
+
+      if (minsym)
+       pst->texthigh = SYMBOL_VALUE_ADDRESS (minsym) + MSYMBOL_SIZE (minsym);
+
+      last_function_name = NULL;
+    }
+
+  /* this test will be true if the last .o file is only data */
+  if (textlow_not_set)
+    pst->textlow = pst->texthigh;
+  else
+    {
+      struct partial_symtab *p1;
+
+      /* If we know our own starting text address, then walk through all other
+         psymtabs for this objfile, and if any didn't know their ending text
+         address, set it to our starting address.  Take care to not set our
+         own ending address to our starting address, nor to set addresses on
+         `dependency' files that have both textlow and texthigh zero.  */
+
+      ALL_OBJFILE_PSYMTABS (objfile, p1)
+      {
+       if (p1->texthigh == 0 && p1->textlow != 0 && p1 != pst)
+         {
+           p1->texthigh = pst->textlow;
+           /* if this file has only data, then make textlow match texthigh */
+           if (p1->textlow == 0)
+             p1->textlow = p1->texthigh;
+         }
+      }
+    }
+
+  /* End of kludge for patching Solaris textlow and texthigh.  */
+#endif /* SOFUN_ADDRESS_MAYBE_MISSING.  */
+
+  pst->n_global_syms =
+    objfile->global_psymbols.next - (objfile->global_psymbols.list + pst->globals_offset);
+  pst->n_static_syms =
+    objfile->static_psymbols.next - (objfile->static_psymbols.list + pst->statics_offset);
+
+  pst->number_of_dependencies = number_dependencies;
+  if (number_dependencies)
+    {
+      pst->dependencies = (struct partial_symtab **)
+       obstack_alloc (&objfile->psymbol_obstack,
+                   number_dependencies * sizeof (struct partial_symtab *));
+      memcpy (pst->dependencies, dependency_list,
+             number_dependencies * sizeof (struct partial_symtab *));
+    }
+  else
+    pst->dependencies = 0;
+
+  for (i = 0; i < num_includes; i++)
+    {
+      struct partial_symtab *subpst =
+      allocate_psymtab (include_list[i], objfile);
+
+      /* Copy the sesction_offsets array from the main psymtab. */
+      subpst->section_offsets = pst->section_offsets;
+      subpst->read_symtab_private =
+       (char *) obstack_alloc (&objfile->psymbol_obstack,
+                               sizeof (struct symloc));
+      LDSYMOFF (subpst) =
+       LDSYMLEN (subpst) =
+       subpst->textlow =
+       subpst->texthigh = 0;
+
+      /* We could save slight bits of space by only making one of these,
+         shared by the entire set of include files.  FIXME-someday.  */
+      subpst->dependencies = (struct partial_symtab **)
+       obstack_alloc (&objfile->psymbol_obstack,
+                      sizeof (struct partial_symtab *));
+      subpst->dependencies[0] = pst;
+      subpst->number_of_dependencies = 1;
+
+      subpst->globals_offset =
+       subpst->n_global_syms =
+       subpst->statics_offset =
+       subpst->n_static_syms = 0;
+
+      subpst->readin = 0;
+      subpst->symtab = 0;
+      subpst->read_symtab = pst->read_symtab;
+    }
+
+  sort_pst_symbols (pst);
+
+  /* If there is already a psymtab or symtab for a file of this name, remove it.
+     (If there is a symtab, more drastic things also happen.)
+     This happens in VxWorks.  */
+  free_named_symtabs (pst->filename);
+
+  if (num_includes == 0
+      && number_dependencies == 0
+      && pst->n_global_syms == 0
+      && pst->n_static_syms == 0
+      && has_line_numbers == 0)
+    {
+      /* Throw away this psymtab, it's empty.  We can't deallocate it, since
+         it is on the obstack, but we can forget to chain it on the list.  */
+      /* Empty psymtabs happen as a result of header files which don't have
+         any symbols in them.  There can be a lot of them.  But this check
+         is wrong, in that a psymtab with N_SLINE entries but nothing else
+         is not empty, but we don't realize that.  Fixing that without slowing
+         things down might be tricky.  */
+
+      discard_psymtab (pst);
+
+      /* Indicate that psymtab was thrown away.  */
+      pst = (struct partial_symtab *) NULL;
+    }
+  return pst;
+}
+\f
+static void
+dbx_psymtab_to_symtab_1 (struct partial_symtab *pst)
+{
+  struct cleanup *old_chain;
+  int i;
+
+  if (!pst)
+    return;
+
+  if (pst->readin)
+    {
+      fprintf_unfiltered (gdb_stderr, "Psymtab for %s already read in.  Shouldn't happen.\n",
+                         pst->filename);
+      return;
+    }
+
+  /* Read in all partial symtabs on which this one is dependent */
+  for (i = 0; i < pst->number_of_dependencies; i++)
+    if (!pst->dependencies[i]->readin)
+      {
+       /* Inform about additional files that need to be read in.  */
+       if (info_verbose)
+         {
+           fputs_filtered (" ", gdb_stdout);
+           wrap_here ("");
+           fputs_filtered ("and ", gdb_stdout);
+           wrap_here ("");
+           printf_filtered ("%s...", pst->dependencies[i]->filename);
+           wrap_here ("");     /* Flush output */
+           gdb_flush (gdb_stdout);
+         }
+       dbx_psymtab_to_symtab_1 (pst->dependencies[i]);
+      }
+
+  if (LDSYMLEN (pst))          /* Otherwise it's a dummy */
+    {
+      /* Init stuff necessary for reading in symbols */
+      stabsread_init ();
+      buildsym_init ();
+      old_chain = make_cleanup (really_free_pendings, 0);
+      file_string_table_offset = FILE_STRING_OFFSET (pst);
+      symbol_size = SYMBOL_SIZE (pst);
+
+      /* Read in this file's symbols */
+      bfd_seek (pst->objfile->obfd, SYMBOL_OFFSET (pst), SEEK_SET);
+      read_ofile_symtab (pst);
+      sort_symtab_syms (pst->symtab);
+
+      do_cleanups (old_chain);
+    }
+
+  pst->readin = 1;
+}
+
+/* Read in all of the symbols for a given psymtab for real.
+   Be verbose about it if the user wants that.  */
+
+static void
+dbx_psymtab_to_symtab (struct partial_symtab *pst)
+{
+  bfd *sym_bfd;
+
+  if (!pst)
+    return;
+
+  if (pst->readin)
+    {
+      fprintf_unfiltered (gdb_stderr, "Psymtab for %s already read in.  Shouldn't happen.\n",
+                         pst->filename);
+      return;
+    }
+
+  if (LDSYMLEN (pst) || pst->number_of_dependencies)
+    {
+      /* Print the message now, before reading the string table,
+         to avoid disconcerting pauses.  */
+      if (info_verbose)
+       {
+         printf_filtered ("Reading in symbols for %s...", pst->filename);
+         gdb_flush (gdb_stdout);
+       }
+
+      sym_bfd = pst->objfile->obfd;
+
+      next_symbol_text_func = dbx_next_symbol_text;
+
+      dbx_psymtab_to_symtab_1 (pst);
+
+      /* Match with global symbols.  This only needs to be done once,
+         after all of the symtabs and dependencies have been read in.   */
+      scan_file_globals (pst->objfile);
+
+      /* Finish up the debug error message.  */
+      if (info_verbose)
+       printf_filtered ("done.\n");
+    }
+}
+
+/* Read in a defined section of a specific object file's symbols. */
+
+static void
+read_ofile_symtab (struct partial_symtab *pst)
+{
+  register char *namestring;
+  register struct external_nlist *bufp;
+  struct internal_nlist nlist;
+  unsigned char type;
+  unsigned max_symnum;
+  register bfd *abfd;
+  struct objfile *objfile;
+  int sym_offset;              /* Offset to start of symbols to read */
+  int sym_size;                        /* Size of symbols to read */
+  CORE_ADDR text_offset;       /* Start of text segment for symbols */
+  int text_size;               /* Size of text segment for symbols */
+  struct section_offsets *section_offsets;
+
+  objfile = pst->objfile;
+  sym_offset = LDSYMOFF (pst);
+  sym_size = LDSYMLEN (pst);
+  text_offset = pst->textlow;
+  text_size = pst->texthigh - pst->textlow;
+  /* This cannot be simply objfile->section_offsets because of
+     elfstab_offset_sections() which initializes the psymtab section
+     offsets information in a special way, and that is different from
+     objfile->section_offsets. */ 
+  section_offsets = pst->section_offsets;
+
+  current_objfile = objfile;
+  subfile_stack = NULL;
+
+  stringtab_global = DBX_STRINGTAB (objfile);
+  last_source_file = NULL;
+
+  abfd = objfile->obfd;
+  symfile_bfd = objfile->obfd; /* Implicit param to next_text_symbol */
+  symbuf_end = symbuf_idx = 0;
+
+  /* It is necessary to actually read one symbol *before* the start
+     of this symtab's symbols, because the GCC_COMPILED_FLAG_SYMBOL
+     occurs before the N_SO symbol.
+
+     Detecting this in read_dbx_symtab
+     would slow down initial readin, so we look for it here instead.  */
+  if (!processing_acc_compilation && sym_offset >= (int) symbol_size)
+    {
+      bfd_seek (symfile_bfd, sym_offset - symbol_size, SEEK_CUR);
+      fill_symbuf (abfd);
+      bufp = &symbuf[symbuf_idx++];
+      INTERNALIZE_SYMBOL (nlist, bufp, abfd);
+      OBJSTAT (objfile, n_stabs++);
+
+      namestring = set_namestring (objfile, nlist);
+
+      processing_gcc_compilation = 0;
+      if (nlist.n_type == N_TEXT)
+       {
+         const char *tempstring = namestring;
+
+         if (STREQ (namestring, GCC_COMPILED_FLAG_SYMBOL))
+           processing_gcc_compilation = 1;
+         else if (STREQ (namestring, GCC2_COMPILED_FLAG_SYMBOL))
+           processing_gcc_compilation = 2;
+         if (tempstring[0] == bfd_get_symbol_leading_char (symfile_bfd))
+           ++tempstring;
+         if (STREQN (tempstring, "__gnu_compiled", 14))
+           processing_gcc_compilation = 2;
+       }
+
+      /* Try to select a C++ demangling based on the compilation unit
+         producer. */
+
+#if 0
+      /* For now, stay with AUTO_DEMANGLING for g++ output, as we don't
+        know whether it will use the old style or v3 mangling.  */
+      if (processing_gcc_compilation)
+       {
+         if (AUTO_DEMANGLING)
+           {
+             set_demangling_style (GNU_DEMANGLING_STYLE_STRING);
+           }
+       }
+#endif
+    }
+  else
+    {
+      /* The N_SO starting this symtab is the first symbol, so we
+         better not check the symbol before it.  I'm not this can
+         happen, but it doesn't hurt to check for it.  */
+      bfd_seek (symfile_bfd, sym_offset, SEEK_CUR);
+      processing_gcc_compilation = 0;
+    }
+
+  if (symbuf_idx == symbuf_end)
+    fill_symbuf (abfd);
+  bufp = &symbuf[symbuf_idx];
+  if (bfd_h_get_8 (abfd, bufp->e_type) != N_SO)
+    error ("First symbol in segment of executable not a source symbol");
+
+  max_symnum = sym_size / symbol_size;
+
+  for (symnum = 0;
+       symnum < max_symnum;
+       symnum++)
+    {
+      QUIT;                    /* Allow this to be interruptable */
+      if (symbuf_idx == symbuf_end)
+       fill_symbuf (abfd);
+      bufp = &symbuf[symbuf_idx++];
+      INTERNALIZE_SYMBOL (nlist, bufp, abfd);
+      OBJSTAT (objfile, n_stabs++);
+
+      type = bfd_h_get_8 (abfd, bufp->e_type);
+
+      namestring = set_namestring (objfile, nlist);
+
+      if (type & N_STAB)
+       {
+         process_one_symbol (type, nlist.n_desc, nlist.n_value,
+                             namestring, section_offsets, objfile);
+       }
+      /* We skip checking for a new .o or -l file; that should never
+         happen in this routine. */
+      else if (type == N_TEXT)
+       {
+         /* I don't think this code will ever be executed, because
+            the GCC_COMPILED_FLAG_SYMBOL usually is right before
+            the N_SO symbol which starts this source file.
+            However, there is no reason not to accept
+            the GCC_COMPILED_FLAG_SYMBOL anywhere.  */
+
+         if (STREQ (namestring, GCC_COMPILED_FLAG_SYMBOL))
+           processing_gcc_compilation = 1;
+         else if (STREQ (namestring, GCC2_COMPILED_FLAG_SYMBOL))
+           processing_gcc_compilation = 2;
+
+#if 0
+         /* For now, stay with AUTO_DEMANGLING for g++ output, as we don't
+            know whether it will use the old style or v3 mangling.  */
+         if (AUTO_DEMANGLING)
+           {
+             set_demangling_style (GNU_DEMANGLING_STYLE_STRING);
+           }
+#endif
+       }
+      else if (type & N_EXT || type == (unsigned char) N_TEXT
+              || type == (unsigned char) N_NBTEXT
+       )
+       {
+         /* Global symbol: see if we came across a dbx defintion for
+            a corresponding symbol.  If so, store the value.  Remove
+            syms from the chain when their values are stored, but
+            search the whole chain, as there may be several syms from
+            different files with the same name. */
+         /* This is probably not true.  Since the files will be read
+            in one at a time, each reference to a global symbol will
+            be satisfied in each file as it appears. So we skip this
+            section. */
+         ;
+       }
+    }
+
+  current_objfile = NULL;
+
+  /* In a Solaris elf file, this variable, which comes from the
+     value of the N_SO symbol, will still be 0.  Luckily, text_offset,
+     which comes from pst->textlow is correct. */
+  if (last_source_start_addr == 0)
+    last_source_start_addr = text_offset;
+
+  /* In reordered executables last_source_start_addr may not be the
+     lower bound for this symtab, instead use text_offset which comes
+     from pst->textlow which is correct.  */
+  if (last_source_start_addr > text_offset)
+    last_source_start_addr = text_offset;
+
+  pst->symtab = end_symtab (text_offset + text_size, objfile, SECT_OFF_TEXT (objfile));
+
+  /* Process items which we had to "process_later" due to dependencies 
+     on other stabs.  */
+  process_now (objfile);
+
+  end_stabs ();
+}
+\f
+
+/* This handles a single symbol from the symbol-file, building symbols
+   into a GDB symtab.  It takes these arguments and an implicit argument.
+
+   TYPE is the type field of the ".stab" symbol entry.
+   DESC is the desc field of the ".stab" entry.
+   VALU is the value field of the ".stab" entry.
+   NAME is the symbol name, in our address space.
+   SECTION_OFFSETS is a set of amounts by which the sections of this object
+   file were relocated when it was loaded into memory.
+   Note that these section_offsets are not the 
+   objfile->section_offsets but the pst->section_offsets.
+   All symbols that refer
+   to memory locations need to be offset by these amounts.
+   OBJFILE is the object file from which we are reading symbols.
+   It is used in end_symtab.  */
+
+void
+process_one_symbol (int type, int desc, CORE_ADDR valu, char *name,
+                   struct section_offsets *section_offsets,
+                   struct objfile *objfile)
+{
+#ifdef SUN_FIXED_LBRAC_BUG
+  /* If SUN_FIXED_LBRAC_BUG is defined, then it tells us whether we need
+     to correct the address of N_LBRAC's.  If it is not defined, then
+     we never need to correct the addresses.  */
+
+  /* This records the last pc address we've seen.  We depend on there being
+     an SLINE or FUN or SO before the first LBRAC, since the variable does
+     not get reset in between reads of different symbol files.  */
+  static CORE_ADDR last_pc_address;
+#endif
+
+  register struct context_stack *new;
+  /* This remembers the address of the start of a function.  It is used
+     because in Solaris 2, N_LBRAC, N_RBRAC, and N_SLINE entries are
+     relative to the current function's start address.  On systems
+     other than Solaris 2, this just holds the SECT_OFF_TEXT value, and is
+     used to relocate these symbol types rather than SECTION_OFFSETS.  */
+  static CORE_ADDR function_start_offset;
+
+  /* This holds the address of the start of a function, without the system
+     peculiarities of function_start_offset.  */
+  static CORE_ADDR last_function_start;
+
+  /* If this is nonzero, we've seen an N_SLINE since the start of the current
+     function.  Initialized to nonzero to assure that last_function_start
+     is never used uninitialized.  */
+  static int sline_found_in_function = 1;
+
+  /* If this is nonzero, we've seen a non-gcc N_OPT symbol for this source
+     file.  Used to detect the SunPRO solaris compiler.  */
+  static int n_opt_found;
+
+  /* The stab type used for the definition of the last function.
+     N_STSYM or N_GSYM for SunOS4 acc; N_FUN for other compilers.  */
+  static int function_stab_type = 0;
+
+  if (!block_address_function_relative)
+    /* N_LBRAC, N_RBRAC and N_SLINE entries are not relative to the
+       function start address, so just use the text offset.  */
+    function_start_offset = ANOFFSET (section_offsets, SECT_OFF_TEXT (objfile));
+
+  /* Something is wrong if we see real data before
+     seeing a source file name.  */
+
+  if (last_source_file == NULL && type != (unsigned char) N_SO)
+    {
+      /* Ignore any symbols which appear before an N_SO symbol.
+         Currently no one puts symbols there, but we should deal
+         gracefully with the case.  A complain()t might be in order,
+         but this should not be an error ().  */
+      return;
+    }
+
+  switch (type)
+    {
+    case N_FUN:
+    case N_FNAME:
+
+      if (*name == '\000')
+       {
+         /* This N_FUN marks the end of a function.  This closes off the
+            current block.  */
+         record_line (current_subfile, 0, function_start_offset + valu);
+         within_function = 0;
+         new = pop_context ();
+
+         /* Make a block for the local symbols within.  */
+         finish_block (new->name, &local_symbols, new->old_blocks,
+                       new->start_addr, new->start_addr + valu,
+                       objfile);
+
+         /* May be switching to an assembler file which may not be using
+            block relative stabs, so reset the offset.  */
+         if (block_address_function_relative)
+           function_start_offset = 0;
+
+         break;
+       }
+
+      sline_found_in_function = 0;
+
+      /* Relocate for dynamic loading */
+      valu += ANOFFSET (section_offsets, SECT_OFF_TEXT (objfile));
+      valu = SMASH_TEXT_ADDRESS (valu);
+      last_function_start = valu;
+
+      goto define_a_symbol;
+
+    case N_LBRAC:
+      /* This "symbol" just indicates the start of an inner lexical
+         context within a function.  */
+
+      /* Ignore extra outermost context from SunPRO cc and acc.  */
+      if (n_opt_found && desc == 1)
+       break;
+
+      if (block_address_function_relative)
+       /* Relocate for Sun ELF acc fn-relative syms.  */
+       valu += function_start_offset;
+      else
+       /* On most machines, the block addresses are relative to the
+          N_SO, the linker did not relocate them (sigh).  */
+       valu += last_source_start_addr;
+
+#ifdef SUN_FIXED_LBRAC_BUG
+      if (!SUN_FIXED_LBRAC_BUG && valu < last_pc_address)
+       {
+         /* Patch current LBRAC pc value to match last handy pc value */
+         complain (&lbrac_complaint);
+         valu = last_pc_address;
+       }
+#endif
+      new = push_context (desc, valu);
+      break;
+
+    case N_RBRAC:
+      /* This "symbol" just indicates the end of an inner lexical
+         context that was started with N_LBRAC.  */
+
+      /* Ignore extra outermost context from SunPRO cc and acc.  */
+      if (n_opt_found && desc == 1)
+       break;
+
+      if (block_address_function_relative)
+       /* Relocate for Sun ELF acc fn-relative syms.  */
+       valu += function_start_offset;
+      else
+       /* On most machines, the block addresses are relative to the
+          N_SO, the linker did not relocate them (sigh).  */
+       valu += last_source_start_addr;
+
+      new = pop_context ();
+      if (desc != new->depth)
+       complain (&lbrac_mismatch_complaint, symnum);
+
+      /* Some compilers put the variable decls inside of an
+         LBRAC/RBRAC block.  This macro should be nonzero if this
+         is true.  DESC is N_DESC from the N_RBRAC symbol.
+         GCC_P is true if we've detected the GCC_COMPILED_SYMBOL
+         or the GCC2_COMPILED_SYMBOL.  */
+#if !defined (VARIABLES_INSIDE_BLOCK)
+#define VARIABLES_INSIDE_BLOCK(desc, gcc_p) 0
+#endif
+
+      /* Can only use new->locals as local symbols here if we're in
+         gcc or on a machine that puts them before the lbrack.  */
+      if (!VARIABLES_INSIDE_BLOCK (desc, processing_gcc_compilation))
+       {
+         if (local_symbols != NULL)
+           {
+             /* GCC development snapshots from March to December of
+                2000 would output N_LSYM entries after N_LBRAC
+                entries.  As a consequence, these symbols are simply
+                discarded.  Complain if this is the case.  Note that
+                there are some compilers which legitimately put local
+                symbols within an LBRAC/RBRAC block; this complaint
+                might also help sort out problems in which
+                VARIABLES_INSIDE_BLOCK is incorrectly defined.  */
+             complain (&discarding_local_symbols_complaint);
+           }
+         local_symbols = new->locals;
+       }
+
+      if (context_stack_depth
+         > !VARIABLES_INSIDE_BLOCK (desc, processing_gcc_compilation))
+       {
+         /* This is not the outermost LBRAC...RBRAC pair in the function,
+            its local symbols preceded it, and are the ones just recovered
+            from the context stack.  Define the block for them (but don't
+            bother if the block contains no symbols.  Should we complain
+            on blocks without symbols?  I can't think of any useful purpose
+            for them).  */
+         if (local_symbols != NULL)
+           {
+             /* Muzzle a compiler bug that makes end < start.  (which
+                compilers?  Is this ever harmful?).  */
+             if (new->start_addr > valu)
+               {
+                 complain (&lbrac_rbrac_complaint);
+                 new->start_addr = valu;
+               }
+             /* Make a block for the local symbols within.  */
+             finish_block (0, &local_symbols, new->old_blocks,
+                           new->start_addr, valu, objfile);
+           }
+       }
+      else
+       {
+         /* This is the outermost LBRAC...RBRAC pair.  There is no
+            need to do anything; leave the symbols that preceded it
+            to be attached to the function's own block.  We need to
+            indicate that we just moved outside of the function.  */
+         within_function = 0;
+       }
+
+      if (VARIABLES_INSIDE_BLOCK (desc, processing_gcc_compilation))
+       /* Now pop locals of block just finished.  */
+       local_symbols = new->locals;
+      break;
+
+    case N_FN:
+    case N_FN_SEQ:
+      /* This kind of symbol indicates the start of an object file.  */
+      /* Relocate for dynamic loading */
+      valu += ANOFFSET (section_offsets, SECT_OFF_TEXT (objfile));
+      break;
+
+    case N_SO:
+      /* This type of symbol indicates the start of data
+         for one source file.
+         Finish the symbol table of the previous source file
+         (if any) and start accumulating a new symbol table.  */
+      /* Relocate for dynamic loading */
+      valu += ANOFFSET (section_offsets, SECT_OFF_TEXT (objfile));
+
+      n_opt_found = 0;
+
+#ifdef SUN_FIXED_LBRAC_BUG
+      last_pc_address = valu;  /* Save for SunOS bug circumcision */
+#endif
+
+#ifdef PCC_SOL_BROKEN
+      /* pcc bug, occasionally puts out SO for SOL.  */
+      if (context_stack_depth > 0)
+       {
+         start_subfile (name, NULL);
+         break;
+       }
+#endif
+      if (last_source_file)
+       {
+         /* Check if previous symbol was also an N_SO (with some
+            sanity checks).  If so, that one was actually the directory
+            name, and the current one is the real file name.
+            Patch things up. */
+         if (previous_stab_code == (unsigned char) N_SO)
+           {
+             patch_subfile_names (current_subfile, name);
+             break;            /* Ignore repeated SOs */
+           }
+         end_symtab (valu, objfile, SECT_OFF_TEXT (objfile));
+         end_stabs ();
+       }
+
+      /* Null name means this just marks the end of text for this .o file.
+         Don't start a new symtab in this case.  */
+      if (*name == '\000')
+       break;
+
+      if (block_address_function_relative)
+       function_start_offset = 0;
+
+      start_stabs ();
+      start_symtab (name, NULL, valu);
+      record_debugformat ("stabs");
+      break;
+
+    case N_SOL:
+      /* This type of symbol indicates the start of data for
+         a sub-source-file, one whose contents were copied or
+         included in the compilation of the main source file
+         (whose name was given in the N_SO symbol.)  */
+      /* Relocate for dynamic loading */
+      valu += ANOFFSET (section_offsets, SECT_OFF_TEXT (objfile));
+      start_subfile (name, current_subfile->dirname);
+      break;
+
+    case N_BINCL:
+      push_subfile ();
+      add_new_header_file (name, valu);
+      start_subfile (name, current_subfile->dirname);
+      break;
+
+    case N_EINCL:
+      start_subfile (pop_subfile (), current_subfile->dirname);
+      break;
+
+    case N_EXCL:
+      add_old_header_file (name, valu);
+      break;
+
+    case N_SLINE:
+      /* This type of "symbol" really just records
+         one line-number -- core-address correspondence.
+         Enter it in the line list for this symbol table.  */
+
+      /* Relocate for dynamic loading and for ELF acc fn-relative syms.  */
+      valu += function_start_offset;
+
+#ifdef SUN_FIXED_LBRAC_BUG
+      last_pc_address = valu;  /* Save for SunOS bug circumcision */
+#endif
+      /* If this is the first SLINE note in the function, record it at
+        the start of the function instead of at the listed location.  */
+      if (within_function && sline_found_in_function == 0)
+       {
+         record_line (current_subfile, desc, last_function_start);
+         sline_found_in_function = 1;
+       }
+      else
+       record_line (current_subfile, desc, valu);
+      break;
+
+    case N_BCOMM:
+      common_block_start (name, objfile);
+      break;
+
+    case N_ECOMM:
+      common_block_end (objfile);
+      break;
+
+      /* The following symbol types need to have the appropriate offset added
+         to their value; then we process symbol definitions in the name.  */
+
+    case N_STSYM:              /* Static symbol in data seg */
+    case N_LCSYM:              /* Static symbol in BSS seg */
+    case N_ROSYM:              /* Static symbol in Read-only data seg */
+      /* HORRID HACK DEPT.  However, it's Sun's furgin' fault.
+         Solaris2's stabs-in-elf makes *most* symbols relative
+         but leaves a few absolute (at least for Solaris 2.1 and version
+         2.0.1 of the SunPRO compiler).  N_STSYM and friends sit on the fence.
+         .stab "foo:S...",N_STSYM        is absolute (ld relocates it)
+         .stab "foo:V...",N_STSYM        is relative (section base subtracted).
+         This leaves us no choice but to search for the 'S' or 'V'...
+         (or pass the whole section_offsets stuff down ONE MORE function
+         call level, which we really don't want to do).  */
+      {
+       char *p;
+
+       /* .o files and NLMs have non-zero text seg offsets, but don't need
+          their static syms offset in this fashion.  XXX - This is really a
+          crock that should be fixed in the solib handling code so that I
+          don't have to work around it here. */
+
+       if (!symfile_relocatable)
+         {
+           p = strchr (name, ':');
+           if (p != 0 && p[1] == 'S')
+             {
+               /* The linker relocated it.  We don't want to add an
+                  elfstab_offset_sections-type offset, but we *do* want
+                  to add whatever solib.c passed to symbol_file_add as
+                  addr (this is known to affect SunOS4, and I suspect ELF
+                  too).  Since elfstab_offset_sections currently does not
+                  muck with the text offset (there is no Ttext.text
+                  symbol), we can get addr from the text offset.  If
+                  elfstab_offset_sections ever starts dealing with the
+                  text offset, and we still need to do this, we need to
+                  invent a SECT_OFF_ADDR_KLUDGE or something.  */
+               valu += ANOFFSET (section_offsets, SECT_OFF_TEXT (objfile));
+               goto define_a_symbol;
+             }
+         }
+       /* Since it's not the kludge case, re-dispatch to the right handler. */
+       switch (type)
+         {
+         case N_STSYM:
+           goto case_N_STSYM;
+         case N_LCSYM:
+           goto case_N_LCSYM;
+         case N_ROSYM:
+           goto case_N_ROSYM;
+         default:
+           internal_error (__FILE__, __LINE__, "failed internal consistency check");
+         }
+      }
+
+    case_N_STSYM:              /* Static symbol in data seg */
+    case N_DSLINE:             /* Source line number, data seg */
+      valu += ANOFFSET (section_offsets, SECT_OFF_DATA (objfile));
+      goto define_a_symbol;
+
+    case_N_LCSYM:              /* Static symbol in BSS seg */
+    case N_BSLINE:             /* Source line number, bss seg */
+      /*   N_BROWS:       overlaps with N_BSLINE */
+      valu += ANOFFSET (section_offsets, SECT_OFF_BSS (objfile));
+      goto define_a_symbol;
+
+    case_N_ROSYM:              /* Static symbol in Read-only data seg */
+      valu += ANOFFSET (section_offsets, SECT_OFF_RODATA (objfile));
+      goto define_a_symbol;
+
+    case N_ENTRY:              /* Alternate entry point */
+      /* Relocate for dynamic loading */
+      valu += ANOFFSET (section_offsets, SECT_OFF_TEXT (objfile));
+      goto define_a_symbol;
+
+      /* The following symbol types we don't know how to process.  Handle
+         them in a "default" way, but complain to people who care.  */
+    default:
+    case N_CATCH:              /* Exception handler catcher */
+    case N_EHDECL:             /* Exception handler name */
+    case N_PC:                 /* Global symbol in Pascal */
+    case N_M2C:                /* Modula-2 compilation unit */
+      /*   N_MOD2:        overlaps with N_EHDECL */
+    case N_SCOPE:              /* Modula-2 scope information */
+    case N_ECOML:              /* End common (local name) */
+    case N_NBTEXT:             /* Gould Non-Base-Register symbols??? */
+    case N_NBDATA:
+    case N_NBBSS:
+    case N_NBSTS:
+    case N_NBLCS:
+      complain (&unknown_symtype_complaint, local_hex_string (type));
+      /* FALLTHROUGH */
+
+      /* The following symbol types don't need the address field relocated,
+         since it is either unused, or is absolute.  */
+    define_a_symbol:
+    case N_GSYM:               /* Global variable */
+    case N_NSYMS:              /* Number of symbols (ultrix) */
+    case N_NOMAP:              /* No map?  (ultrix) */
+    case N_RSYM:               /* Register variable */
+    case N_DEFD:               /* Modula-2 GNU module dependency */
+    case N_SSYM:               /* Struct or union element */
+    case N_LSYM:               /* Local symbol in stack */
+    case N_PSYM:               /* Parameter variable */
+    case N_LENG:               /* Length of preceding symbol type */
+      if (name)
+       {
+         int deftype;
+         char *colon_pos = strchr (name, ':');
+         if (colon_pos == NULL)
+           deftype = '\0';
+         else
+           deftype = colon_pos[1];
+
+         switch (deftype)
+           {
+           case 'f':
+           case 'F':
+             function_stab_type = type;
+
+#ifdef SOFUN_ADDRESS_MAYBE_MISSING
+             /* Deal with the SunPRO 3.0 compiler which omits the address
+                from N_FUN symbols.  */
+             if (type == N_FUN
+                 && valu == ANOFFSET (section_offsets, SECT_OFF_TEXT (objfile)))
+               {
+                 CORE_ADDR minsym_valu = 
+                   find_stab_function_addr (name, last_source_file, objfile);
+
+                 /* find_stab_function_addr will return 0 if the minimal
+                    symbol wasn't found.  (Unfortunately, this might also
+                    be a valid address.)  Anyway, if it *does* return 0,
+                    it is likely that the value was set correctly to begin
+                    with... */
+                 if (minsym_valu != 0)
+                   valu = minsym_valu;
+               }
+#endif
+
+#ifdef SUN_FIXED_LBRAC_BUG
+             /* The Sun acc compiler, under SunOS4, puts out
+                functions with N_GSYM or N_STSYM.  The problem is
+                that the address of the symbol is no good (for N_GSYM
+                it doesn't even attept an address; for N_STSYM it
+                puts out an address but then it gets relocated
+                relative to the data segment, not the text segment).
+                Currently we can't fix this up later as we do for
+                some types of symbol in scan_file_globals.
+                Fortunately we do have a way of finding the address -
+                we know that the value in last_pc_address is either
+                the one we want (if we're dealing with the first
+                function in an object file), or somewhere in the
+                previous function. This means that we can use the
+                minimal symbol table to get the address.  */
+
+             /* Starting with release 3.0, the Sun acc compiler,
+                under SunOS4, puts out functions with N_FUN and a value
+                of zero. This gets relocated to the start of the text
+                segment of the module, which is no good either.
+                Under SunOS4 we can deal with this as N_SLINE and N_SO
+                entries contain valid absolute addresses.
+                Release 3.0 acc also puts out N_OPT entries, which makes
+                it possible to discern acc from cc or gcc.  */
+
+             if (type == N_GSYM || type == N_STSYM
+                 || (type == N_FUN
+                     && n_opt_found && !block_address_function_relative))
+               {
+                 struct minimal_symbol *m;
+                 int l = colon_pos - name;
+
+                 m = lookup_minimal_symbol_by_pc (last_pc_address);
+                 if (m && STREQN (SYMBOL_NAME (m), name, l)
+                     && SYMBOL_NAME (m)[l] == '\0')
+                   /* last_pc_address was in this function */
+                   valu = SYMBOL_VALUE (m);
+                 else if (m && SYMBOL_NAME (m + 1)
+                          && STREQN (SYMBOL_NAME (m + 1), name, l)
+                          && SYMBOL_NAME (m + 1)[l] == '\0')
+                   /* last_pc_address was in last function */
+                   valu = SYMBOL_VALUE (m + 1);
+                 else
+                   /* Not found - use last_pc_address (for finish_block) */
+                   valu = last_pc_address;
+               }
+
+             last_pc_address = valu;   /* Save for SunOS bug circumcision */
+#endif
+
+             if (block_address_function_relative)
+               /* For Solaris 2.0 compilers, the block addresses and
+                  N_SLINE's are relative to the start of the
+                  function.  On normal systems, and when using gcc on
+                  Solaris 2.0, these addresses are just absolute, or
+                  relative to the N_SO, depending on
+                  BLOCK_ADDRESS_ABSOLUTE.  */
+               function_start_offset = valu;
+
+             within_function = 1;
+
+             if (context_stack_depth > 1)
+               {
+                 complain (&lbrac_unmatched_complaint, symnum);
+                 break;
+               }
+
+             if (context_stack_depth > 0)
+               {
+                 new = pop_context ();
+                 /* Make a block for the local symbols within.  */
+                 finish_block (new->name, &local_symbols, new->old_blocks,
+                               new->start_addr, valu, objfile);
+               }
+
+             new = push_context (0, valu);
+             new->name = define_symbol (valu, name, desc, type, objfile);
+             break;
+
+           default:
+             define_symbol (valu, name, desc, type, objfile);
+             break;
+           }
+       }
+      break;
+
+      /* We use N_OPT to carry the gcc2_compiled flag.  Sun uses it
+         for a bunch of other flags, too.  Someday we may parse their
+         flags; for now we ignore theirs and hope they'll ignore ours.  */
+    case N_OPT:                /* Solaris 2:  Compiler options */
+      if (name)
+       {
+         if (STREQ (name, GCC2_COMPILED_FLAG_SYMBOL))
+           {
+             processing_gcc_compilation = 2;
+#if 0                          /* Works, but is experimental.  -fnf */
+             /* For now, stay with AUTO_DEMANGLING for g++ output, as we don't
+                know whether it will use the old style or v3 mangling.  */
+             if (AUTO_DEMANGLING)
+               {
+                 set_demangling_style (GNU_DEMANGLING_STYLE_STRING);
+               }
+#endif
+           }
+         else
+           n_opt_found = 1;
+       }
+      break;
+
+    case N_MAIN:               /* Name of main routine.  */
+      /* FIXME: If one has a symbol file with N_MAIN and then replaces
+        it with a symbol file with "main" and without N_MAIN.  I'm
+        not sure exactly what rule to follow but probably something
+        like: N_MAIN takes precedence over "main" no matter what
+        objfile it is in; If there is more than one N_MAIN, choose
+        the one in the symfile_objfile; If there is more than one
+        N_MAIN within a given objfile, complain() and choose
+        arbitrarily. (kingdon) */
+      if (name != NULL)
+       set_main_name (name);
+      break;
+
+      /* The following symbol types can be ignored.  */
+    case N_OBJ:                /* Solaris 2:  Object file dir and name */
+      /*   N_UNDF:                   Solaris 2:  file separator mark */
+      /*   N_UNDF: -- we will never encounter it, since we only process one
+         file's symbols at once.  */
+    case N_ENDM:               /* Solaris 2:  End of module */
+    case N_ALIAS:              /* SunPro F77: alias name, ignore for now.  */
+      break;
+    }
+
+  /* '#' is a GNU C extension to allow one symbol to refer to another
+     related symbol.
+
+     Generally this is used so that an alias can refer to its main
+     symbol.  */
+  if (name[0] == '#')
+    {
+      /* Initialize symbol reference names and determine if this is 
+         a definition.  If symbol reference is being defined, go 
+         ahead and add it.  Otherwise, just return sym. */
+
+      char *s = name;
+      int refnum;
+
+      /* If this stab defines a new reference ID that is not on the
+         reference list, then put it on the reference list.
+
+         We go ahead and advance NAME past the reference, even though
+         it is not strictly necessary at this time.  */
+      refnum = symbol_reference_defined (&s);
+      if (refnum >= 0)
+       if (!ref_search (refnum))
+         ref_add (refnum, 0, name, valu);
+      name = s;
+    }
+
+
+  previous_stab_code = type;
+}
+\f
+/* FIXME: The only difference between this and elfstab_build_psymtabs
+   is the call to install_minimal_symbols for elf, and the support for
+   split sections.  If the differences are really that small, the code
+   should be shared.  */
+
+/* Scan and build partial symbols for an coff symbol file.
+   The coff file has already been processed to get its minimal symbols.
+
+   This routine is the equivalent of dbx_symfile_init and dbx_symfile_read
+   rolled into one.
+
+   OBJFILE is the object file we are reading symbols from.
+   ADDR is the address relative to which the symbols are (e.g.
+   the base address of the text segment).
+   MAINLINE is true if we are reading the main symbol
+   table (as opposed to a shared lib or dynamically loaded file).
+   TEXTADDR is the address of the text section.
+   TEXTSIZE is the size of the text section.
+   STABSECTS is the list of .stab sections in OBJFILE.
+   STABSTROFFSET and STABSTRSIZE define the location in OBJFILE where the
+   .stabstr section exists.
+
+   This routine is mostly copied from dbx_symfile_init and dbx_symfile_read,
+   adjusted for coff details. */
+
+void
+coffstab_build_psymtabs (struct objfile *objfile, int mainline,
+                        CORE_ADDR textaddr, unsigned int textsize,
+                        struct stab_section_list *stabsects,
+                        file_ptr stabstroffset, unsigned int stabstrsize)
+{
+  int val;
+  bfd *sym_bfd = objfile->obfd;
+  char *name = bfd_get_filename (sym_bfd);
+  struct dbx_symfile_info *info;
+  unsigned int stabsize;
+
+  /* There is already a dbx_symfile_info allocated by our caller.
+     It might even contain some info from the coff symtab to help us.  */
+  info = objfile->sym_stab_info;
+
+  DBX_TEXT_ADDR (objfile) = textaddr;
+  DBX_TEXT_SIZE (objfile) = textsize;
+
+#define        COFF_STABS_SYMBOL_SIZE  12      /* XXX FIXME XXX */
+  DBX_SYMBOL_SIZE (objfile) = COFF_STABS_SYMBOL_SIZE;
+  DBX_STRINGTAB_SIZE (objfile) = stabstrsize;
+
+  if (stabstrsize > bfd_get_size (sym_bfd))
+    error ("ridiculous string table size: %d bytes", stabstrsize);
+  DBX_STRINGTAB (objfile) = (char *)
+    obstack_alloc (&objfile->psymbol_obstack, stabstrsize + 1);
+  OBJSTAT (objfile, sz_strtab += stabstrsize + 1);
+
+  /* Now read in the string table in one big gulp.  */
+
+  val = bfd_seek (sym_bfd, stabstroffset, SEEK_SET);
+  if (val < 0)
+    perror_with_name (name);
+  val = bfd_bread (DBX_STRINGTAB (objfile), stabstrsize, sym_bfd);
+  if (val != stabstrsize)
+    perror_with_name (name);
+
+  stabsread_new_init ();
+  buildsym_new_init ();
+  free_header_files ();
+  init_header_files ();
+
+  processing_acc_compilation = 1;
+
+  /* In a coff file, we've already installed the minimal symbols that came
+     from the coff (non-stab) symbol table, so always act like an
+     incremental load here. */
+  if (stabsects->next == NULL)
+    {
+      stabsize = bfd_section_size (sym_bfd, stabsects->section);
+      DBX_SYMCOUNT (objfile) = stabsize / DBX_SYMBOL_SIZE (objfile);
+      DBX_SYMTAB_OFFSET (objfile) = stabsects->section->filepos;
+    }
+  else
+    {
+      struct stab_section_list *stabsect;
+
+      DBX_SYMCOUNT (objfile) = 0;
+      for (stabsect = stabsects; stabsect != NULL; stabsect = stabsect->next)
+       {
+         stabsize = bfd_section_size (sym_bfd, stabsect->section);
+         DBX_SYMCOUNT (objfile) += stabsize / DBX_SYMBOL_SIZE (objfile);
+       }
+
+      DBX_SYMTAB_OFFSET (objfile) = stabsects->section->filepos;
+
+      symbuf_sections = stabsects->next;
+      symbuf_left = bfd_section_size (sym_bfd, stabsects->section);
+      symbuf_read = 0;
+    }
+
+  dbx_symfile_read (objfile, 0);
+}
+\f
+/* Scan and build partial symbols for an ELF symbol file.
+   This ELF file has already been processed to get its minimal symbols,
+   and any DWARF symbols that were in it.
+
+   This routine is the equivalent of dbx_symfile_init and dbx_symfile_read
+   rolled into one.
+
+   OBJFILE is the object file we are reading symbols from.
+   ADDR is the address relative to which the symbols are (e.g.
+   the base address of the text segment).
+   MAINLINE is true if we are reading the main symbol
+   table (as opposed to a shared lib or dynamically loaded file).
+   STABOFFSET and STABSIZE define the location in OBJFILE where the .stab
+   section exists.
+   STABSTROFFSET and STABSTRSIZE define the location in OBJFILE where the
+   .stabstr section exists.
+
+   This routine is mostly copied from dbx_symfile_init and dbx_symfile_read,
+   adjusted for elf details. */
+
+void
+elfstab_build_psymtabs (struct objfile *objfile, int mainline,
+                       file_ptr staboffset, unsigned int stabsize,
+                       file_ptr stabstroffset, unsigned int stabstrsize)
+{
+  int val;
+  bfd *sym_bfd = objfile->obfd;
+  char *name = bfd_get_filename (sym_bfd);
+  struct dbx_symfile_info *info;
+
+  /* There is already a dbx_symfile_info allocated by our caller.
+     It might even contain some info from the ELF symtab to help us.  */
+  info = objfile->sym_stab_info;
+
+  /* Find the first and last text address.  dbx_symfile_read seems to
+     want this.  */
+  find_text_range (sym_bfd, objfile);
+
+#define        ELF_STABS_SYMBOL_SIZE   12      /* XXX FIXME XXX */
+  DBX_SYMBOL_SIZE (objfile) = ELF_STABS_SYMBOL_SIZE;
+  DBX_SYMCOUNT (objfile) = stabsize / DBX_SYMBOL_SIZE (objfile);
+  DBX_STRINGTAB_SIZE (objfile) = stabstrsize;
+  DBX_SYMTAB_OFFSET (objfile) = staboffset;
+
+  if (stabstrsize > bfd_get_size (sym_bfd))
+    error ("ridiculous string table size: %d bytes", stabstrsize);
+  DBX_STRINGTAB (objfile) = (char *)
+    obstack_alloc (&objfile->psymbol_obstack, stabstrsize + 1);
+  OBJSTAT (objfile, sz_strtab += stabstrsize + 1);
+
+  /* Now read in the string table in one big gulp.  */
+
+  val = bfd_seek (sym_bfd, stabstroffset, SEEK_SET);
+  if (val < 0)
+    perror_with_name (name);
+  val = bfd_bread (DBX_STRINGTAB (objfile), stabstrsize, sym_bfd);
+  if (val != stabstrsize)
+    perror_with_name (name);
+
+  stabsread_new_init ();
+  buildsym_new_init ();
+  free_header_files ();
+  init_header_files ();
+  install_minimal_symbols (objfile);
+
+  processing_acc_compilation = 1;
+
+  /* In an elf file, we've already installed the minimal symbols that came
+     from the elf (non-stab) symbol table, so always act like an
+     incremental load here. */
+  dbx_symfile_read (objfile, 0);
+}
+\f
+/* Scan and build partial symbols for a file with special sections for stabs
+   and stabstrings.  The file has already been processed to get its minimal
+   symbols, and any other symbols that might be necessary to resolve GSYMs.
+
+   This routine is the equivalent of dbx_symfile_init and dbx_symfile_read
+   rolled into one.
+
+   OBJFILE is the object file we are reading symbols from.
+   ADDR is the address relative to which the symbols are (e.g. the base address
+   of the text segment).
+   MAINLINE is true if we are reading the main symbol table (as opposed to a
+   shared lib or dynamically loaded file).
+   STAB_NAME is the name of the section that contains the stabs.
+   STABSTR_NAME is the name of the section that contains the stab strings.
+
+   This routine is mostly copied from dbx_symfile_init and dbx_symfile_read. */
+
+void
+stabsect_build_psymtabs (struct objfile *objfile, int mainline, char *stab_name,
+                        char *stabstr_name, char *text_name)
+{
+  int val;
+  bfd *sym_bfd = objfile->obfd;
+  char *name = bfd_get_filename (sym_bfd);
+  asection *stabsect;
+  asection *stabstrsect;
+  asection *text_sect;
+
+  stabsect = bfd_get_section_by_name (sym_bfd, stab_name);
+  stabstrsect = bfd_get_section_by_name (sym_bfd, stabstr_name);
+
+  if (!stabsect)
+    return;
+
+  if (!stabstrsect)
+    error ("stabsect_build_psymtabs:  Found stabs (%s), but not string section (%s)",
+          stab_name, stabstr_name);
+
+  objfile->sym_stab_info = (struct dbx_symfile_info *)
+    xmalloc (sizeof (struct dbx_symfile_info));
+  memset (objfile->sym_stab_info, 0, sizeof (struct dbx_symfile_info));
+
+  text_sect = bfd_get_section_by_name (sym_bfd, text_name);
+  if (!text_sect)
+    error ("Can't find %s section in symbol file", text_name);
+  DBX_TEXT_ADDR (objfile) = bfd_section_vma (sym_bfd, text_sect);
+  DBX_TEXT_SIZE (objfile) = bfd_section_size (sym_bfd, text_sect);
+
+  DBX_SYMBOL_SIZE (objfile) = sizeof (struct external_nlist);
+  DBX_SYMCOUNT (objfile) = bfd_section_size (sym_bfd, stabsect)
+    / DBX_SYMBOL_SIZE (objfile);
+  DBX_STRINGTAB_SIZE (objfile) = bfd_section_size (sym_bfd, stabstrsect);
+  DBX_SYMTAB_OFFSET (objfile) = stabsect->filepos;     /* XXX - FIXME: POKING INSIDE BFD DATA STRUCTURES */
+
+  if (DBX_STRINGTAB_SIZE (objfile) > bfd_get_size (sym_bfd))
+    error ("ridiculous string table size: %d bytes", DBX_STRINGTAB_SIZE (objfile));
+  DBX_STRINGTAB (objfile) = (char *)
+    obstack_alloc (&objfile->psymbol_obstack, DBX_STRINGTAB_SIZE (objfile) + 1);
+  OBJSTAT (objfile, sz_strtab += DBX_STRINGTAB_SIZE (objfile) + 1);
+
+  /* Now read in the string table in one big gulp.  */
+
+  val = bfd_get_section_contents (sym_bfd,     /* bfd */
+                                 stabstrsect,  /* bfd section */
+                                 DBX_STRINGTAB (objfile),      /* input buffer */
+                                 0,    /* offset into section */
+                                 DBX_STRINGTAB_SIZE (objfile));        /* amount to read */
+
+  if (!val)
+    perror_with_name (name);
+
+  stabsread_new_init ();
+  buildsym_new_init ();
+  free_header_files ();
+  init_header_files ();
+  install_minimal_symbols (objfile);
+
+  /* Now, do an incremental load */
+
+  processing_acc_compilation = 1;
+  dbx_symfile_read (objfile, 0);
+}
+\f
+static struct sym_fns aout_sym_fns =
+{
+  bfd_target_aout_flavour,
+  dbx_new_init,                        /* sym_new_init: init anything gbl to entire symtab */
+  dbx_symfile_init,            /* sym_init: read initial info, setup for sym_read() */
+  dbx_symfile_read,            /* sym_read: read a symbol file into symtab */
+  dbx_symfile_finish,          /* sym_finish: finished with file, cleanup */
+  default_symfile_offsets,     /* sym_offsets: parse user's offsets to internal form */
+  NULL                         /* next: pointer to next struct sym_fns */
+};
+
+void
+_initialize_dbxread (void)
+{
+  add_symtab_fns (&aout_sym_fns);
+}
diff --git a/gdb/dwarf2read.c b/gdb/dwarf2read.c
new file mode 100644 (file)
index 0000000..4ef683c
--- /dev/null
@@ -0,0 +1,6938 @@
+/* DWARF 2 debugging format support for GDB.
+   Copyright 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002
+   Free Software Foundation, Inc.
+
+   Adapted by Gary Funck (gary@intrepid.com), Intrepid Technology,
+   Inc.  with support from Florida State University (under contract
+   with the Ada Joint Program Office), and Silicon Graphics, Inc.
+   Initial contribution by Brent Benson, Harris Computer Systems, Inc.,
+   based on Fred Fish's (Cygnus Support) implementation of DWARF 1
+   support in dwarfread.c
+
+   This file is part of GDB.
+
+   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.  */
+
+#include "defs.h"
+#include "bfd.h"
+#include "symtab.h"
+#include "gdbtypes.h"
+#include "symfile.h"
+#include "objfiles.h"
+#include "elf/dwarf2.h"
+#include "buildsym.h"
+#include "demangle.h"
+#include "expression.h"
+#include "filenames.h" /* for DOSish file names */
+#include "macrotab.h"
+
+#include "language.h"
+#include "complaints.h"
+#include "bcache.h"
+#include <fcntl.h>
+#include "gdb_string.h"
+#include "gdb_assert.h"
+#include <sys/types.h>
+
+#ifndef DWARF2_REG_TO_REGNUM
+#define DWARF2_REG_TO_REGNUM(REG) (REG)
+#endif
+
+#if 0
+/* .debug_info header for a compilation unit
+   Because of alignment constraints, this structure has padding and cannot
+   be mapped directly onto the beginning of the .debug_info section.  */
+typedef struct comp_unit_header
+  {
+    unsigned int length;       /* length of the .debug_info
+                                  contribution */
+    unsigned short version;    /* version number -- 2 for DWARF
+                                  version 2 */
+    unsigned int abbrev_offset;        /* offset into .debug_abbrev section */
+    unsigned char addr_size;   /* byte size of an address -- 4 */
+  }
+_COMP_UNIT_HEADER;
+#define _ACTUAL_COMP_UNIT_HEADER_SIZE 11
+#endif
+
+/* .debug_pubnames header
+   Because of alignment constraints, this structure has padding and cannot
+   be mapped directly onto the beginning of the .debug_info section.  */
+typedef struct pubnames_header
+  {
+    unsigned int length;       /* length of the .debug_pubnames
+                                  contribution  */
+    unsigned char version;     /* version number -- 2 for DWARF
+                                  version 2 */
+    unsigned int info_offset;  /* offset into .debug_info section */
+    unsigned int info_size;    /* byte size of .debug_info section
+                                  portion */
+  }
+_PUBNAMES_HEADER;
+#define _ACTUAL_PUBNAMES_HEADER_SIZE 13
+
+/* .debug_pubnames header
+   Because of alignment constraints, this structure has padding and cannot
+   be mapped directly onto the beginning of the .debug_info section.  */
+typedef struct aranges_header
+  {
+    unsigned int length;       /* byte len of the .debug_aranges
+                                  contribution */
+    unsigned short version;    /* version number -- 2 for DWARF
+                                  version 2 */
+    unsigned int info_offset;  /* offset into .debug_info section */
+    unsigned char addr_size;   /* byte size of an address */
+    unsigned char seg_size;    /* byte size of segment descriptor */
+  }
+_ARANGES_HEADER;
+#define _ACTUAL_ARANGES_HEADER_SIZE 12
+
+/* .debug_line statement program prologue
+   Because of alignment constraints, this structure has padding and cannot
+   be mapped directly onto the beginning of the .debug_info section.  */
+typedef struct statement_prologue
+  {
+    unsigned int total_length; /* byte length of the statement
+                                  information */
+    unsigned short version;    /* version number -- 2 for DWARF
+                                  version 2 */
+    unsigned int prologue_length;      /* # bytes between prologue &
+                                          stmt program */
+    unsigned char minimum_instruction_length;  /* byte size of
+                                                  smallest instr */
+    unsigned char default_is_stmt;     /* initial value of is_stmt
+                                          register */
+    char line_base;
+    unsigned char line_range;
+    unsigned char opcode_base; /* number assigned to first special
+                                  opcode */
+    unsigned char *standard_opcode_lengths;
+  }
+_STATEMENT_PROLOGUE;
+
+/* offsets and sizes of debugging sections */
+
+static file_ptr dwarf_info_offset;
+static file_ptr dwarf_abbrev_offset;
+static file_ptr dwarf_line_offset;
+static file_ptr dwarf_pubnames_offset;
+static file_ptr dwarf_aranges_offset;
+static file_ptr dwarf_loc_offset;
+static file_ptr dwarf_macinfo_offset;
+static file_ptr dwarf_str_offset;
+file_ptr dwarf_frame_offset;
+file_ptr dwarf_eh_frame_offset;
+
+static unsigned int dwarf_info_size;
+static unsigned int dwarf_abbrev_size;
+static unsigned int dwarf_line_size;
+static unsigned int dwarf_pubnames_size;
+static unsigned int dwarf_aranges_size;
+static unsigned int dwarf_loc_size;
+static unsigned int dwarf_macinfo_size;
+static unsigned int dwarf_str_size;
+unsigned int dwarf_frame_size;
+unsigned int dwarf_eh_frame_size;
+
+/* names of the debugging sections */
+
+#define INFO_SECTION     ".debug_info"
+#define ABBREV_SECTION   ".debug_abbrev"
+#define LINE_SECTION     ".debug_line"
+#define PUBNAMES_SECTION ".debug_pubnames"
+#define ARANGES_SECTION  ".debug_aranges"
+#define LOC_SECTION      ".debug_loc"
+#define MACINFO_SECTION  ".debug_macinfo"
+#define STR_SECTION      ".debug_str"
+#define FRAME_SECTION    ".debug_frame"
+#define EH_FRAME_SECTION ".eh_frame"
+
+/* local data types */
+
+/* The data in a compilation unit header, after target2host
+   translation, looks like this.  */
+struct comp_unit_head
+  {
+    unsigned long length;
+    short version;
+    unsigned int abbrev_offset;
+    unsigned char addr_size;
+    unsigned char signed_addr_p;
+    unsigned int offset_size;  /* size of file offsets; either 4 or 8 */
+    unsigned int initial_length_size; /* size of the length field; either
+                                         4 or 12 */
+  };
+
+/* The line number information for a compilation unit (found in the
+   .debug_line section) begins with a "statement program header",
+   which contains the following information.  */
+struct line_header
+{
+  unsigned int total_length;
+  unsigned short version;
+  unsigned int header_length;
+  unsigned char minimum_instruction_length;
+  unsigned char default_is_stmt;
+  int line_base;
+  unsigned char line_range;
+  unsigned char opcode_base;
+
+  /* standard_opcode_lengths[i] is the number of operands for the
+     standard opcode whose value is i.  This means that
+     standard_opcode_lengths[0] is unused, and the last meaningful
+     element is standard_opcode_lengths[opcode_base - 1].  */
+  unsigned char *standard_opcode_lengths;
+
+  /* The include_directories table.  NOTE!  These strings are not
+     allocated with xmalloc; instead, they are pointers into
+     debug_line_buffer.  If you try to free them, `free' will get
+     indigestion.  */
+  unsigned int num_include_dirs, include_dirs_size;
+  char **include_dirs;
+
+  /* The file_names table.  NOTE!  These strings are not allocated
+     with xmalloc; instead, they are pointers into debug_line_buffer.
+     Don't try to free them directly.  */
+  unsigned int num_file_names, file_names_size;
+  struct file_entry
+  {
+    char *name;
+    unsigned int dir_index;
+    unsigned int mod_time;
+    unsigned int length;
+  } *file_names;
+
+  /* The start and end of the statement program following this
+     header.  These point into dwarf_line_buffer.  */
+  char *statement_program_start, *statement_program_end;
+};
+
+/* When we construct a partial symbol table entry we only
+   need this much information. */
+struct partial_die_info
+  {
+    enum dwarf_tag tag;
+    unsigned char has_children;
+    unsigned char is_external;
+    unsigned char is_declaration;
+    unsigned char has_type;
+    unsigned int offset;
+    unsigned int abbrev;
+    char *name;
+    int has_pc_info;
+    CORE_ADDR lowpc;
+    CORE_ADDR highpc;
+    struct dwarf_block *locdesc;
+    unsigned int language;
+    char *sibling;
+  };
+
+/* This data structure holds the information of an abbrev. */
+struct abbrev_info
+  {
+    unsigned int number;       /* number identifying abbrev */
+    enum dwarf_tag tag;                /* dwarf tag */
+    int has_children;          /* boolean */
+    unsigned int num_attrs;    /* number of attributes */
+    struct attr_abbrev *attrs; /* an array of attribute descriptions */
+    struct abbrev_info *next;  /* next in chain */
+  };
+
+struct attr_abbrev
+  {
+    enum dwarf_attribute name;
+    enum dwarf_form form;
+  };
+
+/* This data structure holds a complete die structure. */
+struct die_info
+  {
+    enum dwarf_tag tag;                /* Tag indicating type of die */
+    unsigned short has_children;       /* Does the die have children */
+    unsigned int abbrev;       /* Abbrev number */
+    unsigned int offset;       /* Offset in .debug_info section */
+    unsigned int num_attrs;    /* Number of attributes */
+    struct attribute *attrs;   /* An array of attributes */
+    struct die_info *next_ref; /* Next die in ref hash table */
+    struct die_info *next;     /* Next die in linked list */
+    struct type *type;         /* Cached type information */
+  };
+
+/* Attributes have a name and a value */
+struct attribute
+  {
+    enum dwarf_attribute name;
+    enum dwarf_form form;
+    union
+      {
+       char *str;
+       struct dwarf_block *blk;
+       unsigned long unsnd;
+       long int snd;
+       CORE_ADDR addr;
+      }
+    u;
+  };
+
+struct function_range
+{
+  const char *name;
+  CORE_ADDR lowpc, highpc;
+  int seen_line;
+  struct function_range *next;
+};
+
+static struct function_range *cu_first_fn, *cu_last_fn, *cu_cached_fn;
+
+/* Get at parts of an attribute structure */
+
+#define DW_STRING(attr)    ((attr)->u.str)
+#define DW_UNSND(attr)     ((attr)->u.unsnd)
+#define DW_BLOCK(attr)     ((attr)->u.blk)
+#define DW_SND(attr)       ((attr)->u.snd)
+#define DW_ADDR(attr)     ((attr)->u.addr)
+
+/* Blocks are a bunch of untyped bytes. */
+struct dwarf_block
+  {
+    unsigned int size;
+    char *data;
+  };
+
+/* We only hold one compilation unit's abbrevs in
+   memory at any one time.  */
+#ifndef ABBREV_HASH_SIZE
+#define ABBREV_HASH_SIZE 121
+#endif
+#ifndef ATTR_ALLOC_CHUNK
+#define ATTR_ALLOC_CHUNK 4
+#endif
+
+static struct abbrev_info *dwarf2_abbrevs[ABBREV_HASH_SIZE];
+
+/* A hash table of die offsets for following references.  */
+#ifndef REF_HASH_SIZE
+#define REF_HASH_SIZE 1021
+#endif
+
+static struct die_info *die_ref_table[REF_HASH_SIZE];
+
+/* Obstack for allocating temporary storage used during symbol reading.  */
+static struct obstack dwarf2_tmp_obstack;
+
+/* Offset to the first byte of the current compilation unit header,
+   for resolving relative reference dies. */
+static unsigned int cu_header_offset;
+
+/* Allocate fields for structs, unions and enums in this size.  */
+#ifndef DW_FIELD_ALLOC_CHUNK
+#define DW_FIELD_ALLOC_CHUNK 4
+#endif
+
+/* The language we are debugging.  */
+static enum language cu_language;
+static const struct language_defn *cu_language_defn;
+
+/* Actually data from the sections.  */
+static char *dwarf_info_buffer;
+static char *dwarf_abbrev_buffer;
+static char *dwarf_line_buffer;
+static char *dwarf_str_buffer;
+static char *dwarf_macinfo_buffer;
+
+/* A zeroed version of a partial die for initialization purposes.  */
+static struct partial_die_info zeroed_partial_die;
+
+/* The generic symbol table building routines have separate lists for
+   file scope symbols and all all other scopes (local scopes).  So
+   we need to select the right one to pass to add_symbol_to_list().
+   We do it by keeping a pointer to the correct list in list_in_scope.
+
+   FIXME:  The original dwarf code just treated the file scope as the first
+   local scope, and all other local scopes as nested local scopes, and worked
+   fine.  Check to see if we really need to distinguish these
+   in buildsym.c.  */
+static struct pending **list_in_scope = &file_symbols;
+
+/* FIXME: decode_locdesc sets these variables to describe the location
+   to the caller.  These ought to be a structure or something.   If
+   none of the flags are set, the object lives at the address returned
+   by decode_locdesc.  */
+
+static int optimized_out;      /* No ops in location in expression,
+                                  so object was optimized out.  */
+static int isreg;              /* Object lives in register.
+                                  decode_locdesc's return value is
+                                  the register number.  */
+static int offreg;             /* Object's address is the sum of the
+                                  register specified by basereg, plus
+                                  the offset returned.  */
+static int basereg;            /* See `offreg'.  */
+static int isderef;            /* Value described by flags above is
+                                  the address of a pointer to the object.  */
+static int islocal;            /* Variable is at the returned offset
+                                  from the frame start, but there's
+                                  no identified frame pointer for
+                                  this function, so we can't say
+                                  which register it's relative to;
+                                  use LOC_LOCAL.  */
+
+/* DW_AT_frame_base values for the current function.
+   frame_base_reg is -1 if DW_AT_frame_base is missing, otherwise it
+   contains the register number for the frame register.
+   frame_base_offset is the offset from the frame register to the
+   virtual stack frame. */
+static int frame_base_reg;
+static CORE_ADDR frame_base_offset;
+
+/* This value is added to each symbol value.  FIXME:  Generalize to
+   the section_offsets structure used by dbxread (once this is done,
+   pass the appropriate section number to end_symtab).  */
+static CORE_ADDR baseaddr;     /* Add to each symbol value */
+
+/* We put a pointer to this structure in the read_symtab_private field
+   of the psymtab.
+   The complete dwarf information for an objfile is kept in the
+   psymbol_obstack, so that absolute die references can be handled.
+   Most of the information in this structure is related to an entire
+   object file and could be passed via the sym_private field of the objfile.
+   It is however conceivable that dwarf2 might not be the only type
+   of symbols read from an object file.  */
+
+struct dwarf2_pinfo
+  {
+    /* Pointer to start of dwarf info buffer for the objfile.  */
+
+    char *dwarf_info_buffer;
+
+    /* Offset in dwarf_info_buffer for this compilation unit. */
+
+    unsigned long dwarf_info_offset;
+
+    /* Pointer to start of dwarf abbreviation buffer for the objfile.  */
+
+    char *dwarf_abbrev_buffer;
+
+    /* Size of dwarf abbreviation section for the objfile.  */
+
+    unsigned int dwarf_abbrev_size;
+
+    /* Pointer to start of dwarf line buffer for the objfile.  */
+
+    char *dwarf_line_buffer;
+
+    /* Size of dwarf_line_buffer, in bytes.  */
+    
+    unsigned int dwarf_line_size;
+
+    /* Pointer to start of dwarf string buffer for the objfile.  */
+
+    char *dwarf_str_buffer;
+
+    /* Size of dwarf string section for the objfile.  */
+
+    unsigned int dwarf_str_size;
+
+    /* Pointer to start of dwarf macro buffer for the objfile.  */
+
+    char *dwarf_macinfo_buffer;
+
+    /* Size of dwarf macinfo section for the objfile.  */
+    
+    unsigned int dwarf_macinfo_size;
+
+  };
+
+#define PST_PRIVATE(p) ((struct dwarf2_pinfo *)(p)->read_symtab_private)
+#define DWARF_INFO_BUFFER(p) (PST_PRIVATE(p)->dwarf_info_buffer)
+#define DWARF_INFO_OFFSET(p) (PST_PRIVATE(p)->dwarf_info_offset)
+#define DWARF_ABBREV_BUFFER(p) (PST_PRIVATE(p)->dwarf_abbrev_buffer)
+#define DWARF_ABBREV_SIZE(p) (PST_PRIVATE(p)->dwarf_abbrev_size)
+#define DWARF_LINE_BUFFER(p) (PST_PRIVATE(p)->dwarf_line_buffer)
+#define DWARF_LINE_SIZE(p)   (PST_PRIVATE(p)->dwarf_line_size)
+#define DWARF_STR_BUFFER(p)  (PST_PRIVATE(p)->dwarf_str_buffer)
+#define DWARF_STR_SIZE(p)    (PST_PRIVATE(p)->dwarf_str_size)
+#define DWARF_MACINFO_BUFFER(p) (PST_PRIVATE(p)->dwarf_macinfo_buffer)
+#define DWARF_MACINFO_SIZE(p)   (PST_PRIVATE(p)->dwarf_macinfo_size)
+
+/* Maintain an array of referenced fundamental types for the current
+   compilation unit being read.  For DWARF version 1, we have to construct
+   the fundamental types on the fly, since no information about the
+   fundamental types is supplied.  Each such fundamental type is created by
+   calling a language dependent routine to create the type, and then a
+   pointer to that type is then placed in the array at the index specified
+   by it's FT_<TYPENAME> value.  The array has a fixed size set by the
+   FT_NUM_MEMBERS compile time constant, which is the number of predefined
+   fundamental types gdb knows how to construct.  */
+static struct type *ftypes[FT_NUM_MEMBERS];    /* Fundamental types */
+
+/* FIXME: We might want to set this from BFD via bfd_arch_bits_per_byte,
+   but this would require a corresponding change in unpack_field_as_long
+   and friends.  */
+static int bits_per_byte = 8;
+
+/* The routines that read and process dies for a C struct or C++ class
+   pass lists of data member fields and lists of member function fields
+   in an instance of a field_info structure, as defined below.  */
+struct field_info
+  {
+    /* List of data member and baseclasses fields. */
+    struct nextfield
+      {
+       struct nextfield *next;
+       int accessibility;
+       int virtuality;
+       struct field field;
+      }
+     *fields;
+
+    /* Number of fields.  */
+    int nfields;
+
+    /* Number of baseclasses.  */
+    int nbaseclasses;
+
+    /* Set if the accesibility of one of the fields is not public.  */
+    int non_public_fields;
+
+    /* Member function fields array, entries are allocated in the order they
+       are encountered in the object file.  */
+    struct nextfnfield
+      {
+       struct nextfnfield *next;
+       struct fn_field fnfield;
+      }
+     *fnfields;
+
+    /* Member function fieldlist array, contains name of possibly overloaded
+       member function, number of overloaded member functions and a pointer
+       to the head of the member function field chain.  */
+    struct fnfieldlist
+      {
+       char *name;
+       int length;
+       struct nextfnfield *head;
+      }
+     *fnfieldlists;
+
+    /* Number of entries in the fnfieldlists array.  */
+    int nfnfields;
+  };
+
+/* Various complaints about symbol reading that don't abort the process */
+
+static struct complaint dwarf2_const_ignored =
+{
+  "type qualifier 'const' ignored", 0, 0
+};
+static struct complaint dwarf2_volatile_ignored =
+{
+  "type qualifier 'volatile' ignored", 0, 0
+};
+static struct complaint dwarf2_non_const_array_bound_ignored =
+{
+  "non-constant array bounds form '%s' ignored", 0, 0
+};
+static struct complaint dwarf2_missing_line_number_section =
+{
+  "missing .debug_line section", 0, 0
+};
+static struct complaint dwarf2_statement_list_fits_in_line_number_section =
+{
+  "statement list doesn't fit in .debug_line section", 0, 0
+};
+static struct complaint dwarf2_mangled_line_number_section =
+{
+  "mangled .debug_line section", 0, 0
+};
+static struct complaint dwarf2_unsupported_die_ref_attr =
+{
+  "unsupported die ref attribute form: '%s'", 0, 0
+};
+static struct complaint dwarf2_unsupported_stack_op =
+{
+  "unsupported stack op: '%s'", 0, 0
+};
+static struct complaint dwarf2_complex_location_expr =
+{
+  "location expression too complex", 0, 0
+};
+static struct complaint dwarf2_unsupported_tag =
+{
+  "unsupported tag: '%s'", 0, 0
+};
+static struct complaint dwarf2_unsupported_at_encoding =
+{
+  "unsupported DW_AT_encoding: '%s'", 0, 0
+};
+static struct complaint dwarf2_unsupported_at_frame_base =
+{
+  "unsupported DW_AT_frame_base for function '%s'", 0, 0
+};
+static struct complaint dwarf2_unexpected_tag =
+{
+  "unexepected tag in read_type_die: '%s'", 0, 0
+};
+static struct complaint dwarf2_missing_at_frame_base =
+{
+  "DW_AT_frame_base missing for DW_OP_fbreg", 0, 0
+};
+static struct complaint dwarf2_bad_static_member_name =
+{
+  "unrecognized static data member name '%s'", 0, 0
+};
+static struct complaint dwarf2_unsupported_accessibility =
+{
+  "unsupported accessibility %d", 0, 0
+};
+static struct complaint dwarf2_bad_member_name_complaint =
+{
+  "cannot extract member name from '%s'", 0, 0
+};
+static struct complaint dwarf2_missing_member_fn_type_complaint =
+{
+  "member function type missing for '%s'", 0, 0
+};
+static struct complaint dwarf2_vtbl_not_found_complaint =
+{
+  "virtual function table pointer not found when defining class '%s'", 0, 0
+};
+static struct complaint dwarf2_absolute_sibling_complaint =
+{
+  "ignoring absolute DW_AT_sibling", 0, 0
+};
+static struct complaint dwarf2_const_value_length_mismatch =
+{
+  "const value length mismatch for '%s', got %d, expected %d", 0, 0
+};
+static struct complaint dwarf2_unsupported_const_value_attr =
+{
+  "unsupported const value attribute form: '%s'", 0, 0
+};
+static struct complaint dwarf2_misplaced_line_number =
+{
+  "misplaced first line number at 0x%lx for '%s'", 0, 0
+};
+static struct complaint dwarf2_line_header_too_long =
+{
+  "line number info header doesn't fit in `.debug_line' section", 0, 0
+};
+static struct complaint dwarf2_missing_macinfo_section =
+{
+  "missing .debug_macinfo section", 0, 0
+};
+static struct complaint dwarf2_macros_too_long =
+{
+  "macro info runs off end of `.debug_macinfo' section", 0, 0
+};
+static struct complaint dwarf2_macros_not_terminated =
+{
+  "no terminating 0-type entry for macros in `.debug_macinfo' section", 0, 0
+};
+static struct complaint dwarf2_macro_outside_file =
+{
+  "debug info gives macro %s outside of any file: %s", 0, 0
+};
+static struct complaint dwarf2_macro_unmatched_end_file =
+{
+  "macro debug info has an unmatched `close_file' directive", 0, 0
+};
+static struct complaint dwarf2_macro_malformed_definition =
+{
+  "macro debug info contains a malformed macro definition:\n`%s'", 0, 0
+};
+static struct complaint dwarf2_macro_spaces_in_definition =
+{
+  "macro definition contains spaces in formal argument list:\n`%s'", 0, 0
+};
+static struct complaint dwarf2_invalid_attrib_class =
+{
+  "invalid attribute class or form for '%s' in '%s'", 0, 0
+};
+
+/* local function prototypes */
+
+static void dwarf2_locate_sections (bfd *, asection *, PTR);
+
+#if 0
+static void dwarf2_build_psymtabs_easy (struct objfile *, int);
+#endif
+
+static void dwarf2_build_psymtabs_hard (struct objfile *, int);
+
+static char *scan_partial_symbols (char *, struct objfile *,
+                                  CORE_ADDR *, CORE_ADDR *,
+                                  const struct comp_unit_head *);
+
+static void add_partial_symbol (struct partial_die_info *, struct objfile *,
+                               const struct comp_unit_head *);
+
+static void dwarf2_psymtab_to_symtab (struct partial_symtab *);
+
+static void psymtab_to_symtab_1 (struct partial_symtab *);
+
+char *dwarf2_read_section (struct objfile *, file_ptr, unsigned int);
+
+static void dwarf2_read_abbrevs (bfd *, unsigned int);
+
+static void dwarf2_empty_abbrev_table (PTR);
+
+static struct abbrev_info *dwarf2_lookup_abbrev (unsigned int);
+
+static char *read_partial_die (struct partial_die_info *,
+                              bfd *, char *,
+                              const struct comp_unit_head *);
+
+static char *read_full_die (struct die_info **, bfd *, char *,
+                           const struct comp_unit_head *);
+
+static char *read_attribute (struct attribute *, struct attr_abbrev *,
+                            bfd *, char *, const struct comp_unit_head *);
+
+static char *read_attribute_value (struct attribute *, unsigned,
+                            bfd *, char *, const struct comp_unit_head *);
+
+static unsigned int read_1_byte (bfd *, char *);
+
+static int read_1_signed_byte (bfd *, char *);
+
+static unsigned int read_2_bytes (bfd *, char *);
+
+static unsigned int read_4_bytes (bfd *, char *);
+
+static unsigned long read_8_bytes (bfd *, char *);
+
+static CORE_ADDR read_address (bfd *, char *ptr, const struct comp_unit_head *,
+                              int *bytes_read);
+
+static LONGEST read_initial_length (bfd *, char *,
+                                    struct comp_unit_head *, int *bytes_read);
+
+static LONGEST read_offset (bfd *, char *, const struct comp_unit_head *,
+                            int *bytes_read);
+
+static char *read_n_bytes (bfd *, char *, unsigned int);
+
+static char *read_string (bfd *, char *, unsigned int *);
+
+static char *read_indirect_string (bfd *, char *, const struct comp_unit_head *,
+                                  unsigned int *);
+
+static unsigned long read_unsigned_leb128 (bfd *, char *, unsigned int *);
+
+static long read_signed_leb128 (bfd *, char *, unsigned int *);
+
+static void set_cu_language (unsigned int);
+
+static struct attribute *dwarf_attr (struct die_info *, unsigned int);
+
+static int die_is_declaration (struct die_info *);
+
+static void free_line_header (struct line_header *lh);
+
+static struct line_header *(dwarf_decode_line_header
+                            (unsigned int offset,
+                             bfd *abfd,
+                             const struct comp_unit_head *cu_header));
+
+static void dwarf_decode_lines (struct line_header *, char *, bfd *,
+                               const struct comp_unit_head *);
+
+static void dwarf2_start_subfile (char *, char *);
+
+static struct symbol *new_symbol (struct die_info *, struct type *,
+                                 struct objfile *, const struct comp_unit_head *);
+
+static void dwarf2_const_value (struct attribute *, struct symbol *,
+                               struct objfile *, const struct comp_unit_head *);
+
+static void dwarf2_const_value_data (struct attribute *attr,
+                                    struct symbol *sym,
+                                    int bits);
+
+static struct type *die_type (struct die_info *, struct objfile *,
+                             const struct comp_unit_head *);
+
+static struct type *die_containing_type (struct die_info *, struct objfile *,
+                                        const struct comp_unit_head *);
+
+#if 0
+static struct type *type_at_offset (unsigned int, struct objfile *);
+#endif
+
+static struct type *tag_type_to_type (struct die_info *, struct objfile *,
+                                     const struct comp_unit_head *);
+
+static void read_type_die (struct die_info *, struct objfile *,
+                          const struct comp_unit_head *);
+
+static void read_typedef (struct die_info *, struct objfile *,
+                         const struct comp_unit_head *);
+
+static void read_base_type (struct die_info *, struct objfile *);
+
+static void read_file_scope (struct die_info *, struct objfile *,
+                            const struct comp_unit_head *);
+
+static void read_func_scope (struct die_info *, struct objfile *,
+                            const struct comp_unit_head *);
+
+static void read_lexical_block_scope (struct die_info *, struct objfile *,
+                                     const struct comp_unit_head *);
+
+static int dwarf2_get_pc_bounds (struct die_info *,
+                                CORE_ADDR *, CORE_ADDR *, struct objfile *);
+
+static void dwarf2_add_field (struct field_info *, struct die_info *,
+                             struct objfile *, const struct comp_unit_head *);
+
+static void dwarf2_attach_fields_to_type (struct field_info *,
+                                         struct type *, struct objfile *);
+
+static void dwarf2_add_member_fn (struct field_info *,
+                                 struct die_info *, struct type *,
+                                 struct objfile *objfile,
+                                 const struct comp_unit_head *);
+
+static void dwarf2_attach_fn_fields_to_type (struct field_info *,
+                                            struct type *, struct objfile *);
+
+static void read_structure_scope (struct die_info *, struct objfile *,
+                                 const struct comp_unit_head *);
+
+static void read_common_block (struct die_info *, struct objfile *,
+                              const struct comp_unit_head *);
+
+static void read_enumeration (struct die_info *, struct objfile *,
+                             const struct comp_unit_head *);
+
+static struct type *dwarf_base_type (int, int, struct objfile *);
+
+static CORE_ADDR decode_locdesc (struct dwarf_block *, struct objfile *,
+                                const struct comp_unit_head *);
+
+static void read_array_type (struct die_info *, struct objfile *,
+                            const struct comp_unit_head *);
+
+static void read_tag_pointer_type (struct die_info *, struct objfile *,
+                                  const struct comp_unit_head *);
+
+static void read_tag_ptr_to_member_type (struct die_info *, struct objfile *,
+                                        const struct comp_unit_head *);
+
+static void read_tag_reference_type (struct die_info *, struct objfile *,
+                                    const struct comp_unit_head *);
+
+static void read_tag_const_type (struct die_info *, struct objfile *,
+                                const struct comp_unit_head *);
+
+static void read_tag_volatile_type (struct die_info *, struct objfile *,
+                                   const struct comp_unit_head *);
+
+static void read_tag_string_type (struct die_info *, struct objfile *);
+
+static void read_subroutine_type (struct die_info *, struct objfile *,
+                                 const struct comp_unit_head *);
+
+static struct die_info *read_comp_unit (char *, bfd *,
+                                        const struct comp_unit_head *);
+
+static void free_die_list (struct die_info *);
+
+static struct cleanup *make_cleanup_free_die_list (struct die_info *);
+
+static void process_die (struct die_info *, struct objfile *,
+                        const struct comp_unit_head *);
+
+static char *dwarf2_linkage_name (struct die_info *);
+
+static char *dwarf_tag_name (unsigned int);
+
+static char *dwarf_attr_name (unsigned int);
+
+static char *dwarf_form_name (unsigned int);
+
+static char *dwarf_stack_op_name (unsigned int);
+
+static char *dwarf_bool_name (unsigned int);
+
+static char *dwarf_type_encoding_name (unsigned int);
+
+#if 0
+static char *dwarf_cfi_name (unsigned int);
+
+struct die_info *copy_die (struct die_info *);
+#endif
+
+static struct die_info *sibling_die (struct die_info *);
+
+static void dump_die (struct die_info *);
+
+static void dump_die_list (struct die_info *);
+
+static void store_in_ref_table (unsigned int, struct die_info *);
+
+static void dwarf2_empty_hash_tables (void);
+
+static unsigned int dwarf2_get_ref_die_offset (struct attribute *);
+
+static struct die_info *follow_die_ref (unsigned int);
+
+static struct type *dwarf2_fundamental_type (struct objfile *, int);
+
+/* memory allocation interface */
+
+static void dwarf2_free_tmp_obstack (PTR);
+
+static struct dwarf_block *dwarf_alloc_block (void);
+
+static struct abbrev_info *dwarf_alloc_abbrev (void);
+
+static struct die_info *dwarf_alloc_die (void);
+
+static void initialize_cu_func_list (void);
+
+static void add_to_cu_func_list (const char *, CORE_ADDR, CORE_ADDR);
+
+static void dwarf_decode_macros (struct line_header *, unsigned int,
+                                 char *, bfd *, const struct comp_unit_head *,
+                                 struct objfile *);
+
+static int attr_form_is_block (struct attribute *);
+
+/* Try to locate the sections we need for DWARF 2 debugging
+   information and return true if we have enough to do something.  */
+
+int
+dwarf2_has_info (bfd *abfd)
+{
+  dwarf_info_offset = 0;
+  dwarf_abbrev_offset = 0;
+  dwarf_line_offset = 0;
+  dwarf_str_offset = 0;
+  dwarf_macinfo_offset = 0;
+  dwarf_frame_offset = 0;
+  dwarf_eh_frame_offset = 0;
+  bfd_map_over_sections (abfd, dwarf2_locate_sections, NULL);
+  if (dwarf_info_offset && dwarf_abbrev_offset)
+    {
+      return 1;
+    }
+  else
+    {
+      return 0;
+    }
+}
+
+/* This function is mapped across the sections and remembers the
+   offset and size of each of the debugging sections we are interested
+   in.  */
+
+static void
+dwarf2_locate_sections (bfd *ignore_abfd, asection *sectp, PTR ignore_ptr)
+{
+  if (STREQ (sectp->name, INFO_SECTION))
+    {
+      dwarf_info_offset = sectp->filepos;
+      dwarf_info_size = bfd_get_section_size_before_reloc (sectp);
+    }
+  else if (STREQ (sectp->name, ABBREV_SECTION))
+    {
+      dwarf_abbrev_offset = sectp->filepos;
+      dwarf_abbrev_size = bfd_get_section_size_before_reloc (sectp);
+    }
+  else if (STREQ (sectp->name, LINE_SECTION))
+    {
+      dwarf_line_offset = sectp->filepos;
+      dwarf_line_size = bfd_get_section_size_before_reloc (sectp);
+    }
+  else if (STREQ (sectp->name, PUBNAMES_SECTION))
+    {
+      dwarf_pubnames_offset = sectp->filepos;
+      dwarf_pubnames_size = bfd_get_section_size_before_reloc (sectp);
+    }
+  else if (STREQ (sectp->name, ARANGES_SECTION))
+    {
+      dwarf_aranges_offset = sectp->filepos;
+      dwarf_aranges_size = bfd_get_section_size_before_reloc (sectp);
+    }
+  else if (STREQ (sectp->name, LOC_SECTION))
+    {
+      dwarf_loc_offset = sectp->filepos;
+      dwarf_loc_size = bfd_get_section_size_before_reloc (sectp);
+    }
+  else if (STREQ (sectp->name, MACINFO_SECTION))
+    {
+      dwarf_macinfo_offset = sectp->filepos;
+      dwarf_macinfo_size = bfd_get_section_size_before_reloc (sectp);
+    }
+  else if (STREQ (sectp->name, STR_SECTION))
+    {
+      dwarf_str_offset = sectp->filepos;
+      dwarf_str_size = bfd_get_section_size_before_reloc (sectp);
+    }
+  else if (STREQ (sectp->name, FRAME_SECTION))
+    {
+      dwarf_frame_offset = sectp->filepos;
+      dwarf_frame_size = bfd_get_section_size_before_reloc (sectp);
+    }
+  else if (STREQ (sectp->name, EH_FRAME_SECTION))
+    {
+      dwarf_eh_frame_offset = sectp->filepos;
+      dwarf_eh_frame_size = bfd_get_section_size_before_reloc (sectp);
+    }
+}
+
+/* Build a partial symbol table.  */
+
+void
+dwarf2_build_psymtabs (struct objfile *objfile, int mainline)
+{
+
+  /* We definitely need the .debug_info and .debug_abbrev sections */
+
+  dwarf_info_buffer = dwarf2_read_section (objfile,
+                                          dwarf_info_offset,
+                                          dwarf_info_size);
+  dwarf_abbrev_buffer = dwarf2_read_section (objfile,
+                                            dwarf_abbrev_offset,
+                                            dwarf_abbrev_size);
+
+  if (dwarf_line_offset)
+    dwarf_line_buffer = dwarf2_read_section (objfile,
+                                            dwarf_line_offset,
+                                            dwarf_line_size);
+  else
+    dwarf_line_buffer = NULL;
+
+  if (dwarf_str_offset)
+    dwarf_str_buffer = dwarf2_read_section (objfile,
+                                           dwarf_str_offset,
+                                           dwarf_str_size);
+  else
+    dwarf_str_buffer = NULL;
+
+  if (dwarf_macinfo_offset)
+    dwarf_macinfo_buffer = dwarf2_read_section (objfile,
+                                                dwarf_macinfo_offset,
+                                                dwarf_macinfo_size);
+  else
+    dwarf_macinfo_buffer = NULL;
+
+  if (mainline
+      || (objfile->global_psymbols.size == 0
+         && objfile->static_psymbols.size == 0))
+    {
+      init_psymbol_list (objfile, 1024);
+    }
+
+#if 0
+  if (dwarf_aranges_offset && dwarf_pubnames_offset)
+    {
+      /* Things are significantly easier if we have .debug_aranges and
+         .debug_pubnames sections */
+
+      dwarf2_build_psymtabs_easy (objfile, mainline);
+    }
+  else
+#endif
+    /* only test this case for now */
+    {
+      /* In this case we have to work a bit harder */
+      dwarf2_build_psymtabs_hard (objfile, mainline);
+    }
+}
+
+#if 0
+/* Build the partial symbol table from the information in the
+   .debug_pubnames and .debug_aranges sections.  */
+
+static void
+dwarf2_build_psymtabs_easy (struct objfile *objfile, int mainline)
+{
+  bfd *abfd = objfile->obfd;
+  char *aranges_buffer, *pubnames_buffer;
+  char *aranges_ptr, *pubnames_ptr;
+  unsigned int entry_length, version, info_offset, info_size;
+
+  pubnames_buffer = dwarf2_read_section (objfile,
+                                        dwarf_pubnames_offset,
+                                        dwarf_pubnames_size);
+  pubnames_ptr = pubnames_buffer;
+  while ((pubnames_ptr - pubnames_buffer) < dwarf_pubnames_size)
+    {
+      struct comp_unit_head cu_header;
+      int bytes_read;
+
+      entry_length = read_initial_length (abfd, pubnames_ptr, &cu_header,
+                                         &bytes_read);
+      pubnames_ptr += bytes_read;
+      version = read_1_byte (abfd, pubnames_ptr);
+      pubnames_ptr += 1;
+      info_offset = read_4_bytes (abfd, pubnames_ptr);
+      pubnames_ptr += 4;
+      info_size = read_4_bytes (abfd, pubnames_ptr);
+      pubnames_ptr += 4;
+    }
+
+  aranges_buffer = dwarf2_read_section (objfile,
+                                       dwarf_aranges_offset,
+                                       dwarf_aranges_size);
+
+}
+#endif
+
+/* Read in the comp unit header information from the debug_info at
+   info_ptr. */
+
+static char *
+read_comp_unit_head (struct comp_unit_head *cu_header,
+                    char *info_ptr, bfd *abfd)
+{
+  int signed_addr;
+  int bytes_read;
+  cu_header->length = read_initial_length (abfd, info_ptr, cu_header,
+                                           &bytes_read);
+  info_ptr += bytes_read;
+  cu_header->version = read_2_bytes (abfd, info_ptr);
+  info_ptr += 2;
+  cu_header->abbrev_offset = read_offset (abfd, info_ptr, cu_header,
+                                          &bytes_read);
+  info_ptr += bytes_read;
+  cu_header->addr_size = read_1_byte (abfd, info_ptr);
+  info_ptr += 1;
+  signed_addr = bfd_get_sign_extend_vma (abfd);
+  if (signed_addr < 0)
+    internal_error (__FILE__, __LINE__,
+                   "read_comp_unit_head: dwarf from non elf file");
+  cu_header->signed_addr_p = signed_addr;
+  return info_ptr;
+}
+
+/* Build the partial symbol table by doing a quick pass through the
+   .debug_info and .debug_abbrev sections.  */
+
+static void
+dwarf2_build_psymtabs_hard (struct objfile *objfile, int mainline)
+{
+  /* Instead of reading this into a big buffer, we should probably use
+     mmap()  on architectures that support it. (FIXME) */
+  bfd *abfd = objfile->obfd;
+  char *info_ptr, *abbrev_ptr;
+  char *beg_of_comp_unit;
+  struct partial_die_info comp_unit_die;
+  struct partial_symtab *pst;
+  struct cleanup *back_to;
+  CORE_ADDR lowpc, highpc;
+
+  info_ptr = dwarf_info_buffer;
+  abbrev_ptr = dwarf_abbrev_buffer;
+
+  /* We use dwarf2_tmp_obstack for objects that don't need to survive
+     the partial symbol scan, like attribute values.
+
+     We could reduce our peak memory consumption during partial symbol
+     table construction by freeing stuff from this obstack more often
+     --- say, after processing each compilation unit, or each die ---
+     but it turns out that this saves almost nothing.  For an
+     executable with 11Mb of Dwarf 2 data, I found about 64k allocated
+     on dwarf2_tmp_obstack.  Some investigation showed:
+
+     1) 69% of the attributes used forms DW_FORM_addr, DW_FORM_data*,
+        DW_FORM_flag, DW_FORM_[su]data, and DW_FORM_ref*.  These are
+        all fixed-length values not requiring dynamic allocation.
+
+     2) 30% of the attributes used the form DW_FORM_string.  For
+        DW_FORM_string, read_attribute simply hands back a pointer to
+        the null-terminated string in dwarf_info_buffer, so no dynamic
+        allocation is needed there either.
+
+     3) The remaining 1% of the attributes all used DW_FORM_block1.
+        75% of those were DW_AT_frame_base location lists for
+        functions; the rest were DW_AT_location attributes, probably
+        for the global variables.
+
+     Anyway, what this all means is that the memory the dwarf2
+     reader uses as temporary space reading partial symbols is about
+     0.5% as much as we use for dwarf_*_buffer.  That's noise.  */
+
+  obstack_init (&dwarf2_tmp_obstack);
+  back_to = make_cleanup (dwarf2_free_tmp_obstack, NULL);
+
+  /* Since the objects we're extracting from dwarf_info_buffer vary in
+     length, only the individual functions to extract them (like
+     read_comp_unit_head and read_partial_die) can really know whether
+     the buffer is large enough to hold another complete object.
+
+     At the moment, they don't actually check that.  If
+     dwarf_info_buffer holds just one extra byte after the last
+     compilation unit's dies, then read_comp_unit_head will happily
+     read off the end of the buffer.  read_partial_die is similarly
+     casual.  Those functions should be fixed.
+
+     For this loop condition, simply checking whether there's any data
+     left at all should be sufficient.  */
+  while (info_ptr < dwarf_info_buffer + dwarf_info_size)
+    {
+      struct comp_unit_head cu_header;
+      beg_of_comp_unit = info_ptr;
+      info_ptr = read_comp_unit_head (&cu_header, info_ptr, abfd);
+
+      if (cu_header.version != 2)
+       {
+         error ("Dwarf Error: wrong version in compilation unit header.");
+         return;
+       }
+      if (cu_header.abbrev_offset >= dwarf_abbrev_size)
+       {
+         error ("Dwarf Error: bad offset (0x%lx) in compilation unit header (offset 0x%lx + 6).",
+                (long) cu_header.abbrev_offset,
+                (long) (beg_of_comp_unit - dwarf_info_buffer));
+         return;
+       }
+      if (beg_of_comp_unit + cu_header.length + cu_header.initial_length_size
+         > dwarf_info_buffer + dwarf_info_size)
+       {
+         error ("Dwarf Error: bad length (0x%lx) in compilation unit header (offset 0x%lx + 0).",
+                (long) cu_header.length,
+                (long) (beg_of_comp_unit - dwarf_info_buffer));
+         return;
+       }
+      /* Read the abbrevs for this compilation unit into a table */
+      dwarf2_read_abbrevs (abfd, cu_header.abbrev_offset);
+      make_cleanup (dwarf2_empty_abbrev_table, NULL);
+
+      /* Read the compilation unit die */
+      info_ptr = read_partial_die (&comp_unit_die, abfd, info_ptr,
+                                  &cu_header);
+
+      /* Set the language we're debugging */
+      set_cu_language (comp_unit_die.language);
+
+      /* Allocate a new partial symbol table structure */
+      pst = start_psymtab_common (objfile, objfile->section_offsets,
+                                 comp_unit_die.name ? comp_unit_die.name : "",
+                                 comp_unit_die.lowpc,
+                                 objfile->global_psymbols.next,
+                                 objfile->static_psymbols.next);
+
+      pst->read_symtab_private = (char *)
+       obstack_alloc (&objfile->psymbol_obstack, sizeof (struct dwarf2_pinfo));
+      cu_header_offset = beg_of_comp_unit - dwarf_info_buffer;
+      DWARF_INFO_BUFFER (pst) = dwarf_info_buffer;
+      DWARF_INFO_OFFSET (pst) = beg_of_comp_unit - dwarf_info_buffer;
+      DWARF_ABBREV_BUFFER (pst) = dwarf_abbrev_buffer;
+      DWARF_ABBREV_SIZE (pst) = dwarf_abbrev_size;
+      DWARF_LINE_BUFFER (pst) = dwarf_line_buffer;
+      DWARF_LINE_SIZE (pst) = dwarf_line_size;
+      DWARF_STR_BUFFER (pst) = dwarf_str_buffer;
+      DWARF_STR_SIZE (pst) = dwarf_str_size;
+      DWARF_MACINFO_BUFFER (pst) = dwarf_macinfo_buffer;
+      DWARF_MACINFO_SIZE (pst) = dwarf_macinfo_size;
+      baseaddr = ANOFFSET (objfile->section_offsets, SECT_OFF_TEXT (objfile));
+
+      /* Store the function that reads in the rest of the symbol table */
+      pst->read_symtab = dwarf2_psymtab_to_symtab;
+
+      /* Check if comp unit has_children.
+         If so, read the rest of the partial symbols from this comp unit.
+         If not, there's no more debug_info for this comp unit. */
+      if (comp_unit_die.has_children)
+       {
+         info_ptr = scan_partial_symbols (info_ptr, objfile, &lowpc, &highpc,
+                                          &cu_header);
+
+         /* If the compilation unit didn't have an explicit address range,
+            then use the information extracted from its child dies.  */
+         if (! comp_unit_die.has_pc_info)
+           {
+             comp_unit_die.lowpc = lowpc;
+             comp_unit_die.highpc = highpc;
+           }
+       }
+      pst->textlow = comp_unit_die.lowpc + baseaddr;
+      pst->texthigh = comp_unit_die.highpc + baseaddr;
+
+      pst->n_global_syms = objfile->global_psymbols.next -
+       (objfile->global_psymbols.list + pst->globals_offset);
+      pst->n_static_syms = objfile->static_psymbols.next -
+       (objfile->static_psymbols.list + pst->statics_offset);
+      sort_pst_symbols (pst);
+
+      /* If there is already a psymtab or symtab for a file of this
+         name, remove it. (If there is a symtab, more drastic things
+         also happen.) This happens in VxWorks.  */
+      free_named_symtabs (pst->filename);
+
+      info_ptr = beg_of_comp_unit + cu_header.length 
+                                  + cu_header.initial_length_size;
+    }
+  do_cleanups (back_to);
+}
+
+/* Read in all interesting dies to the end of the compilation unit.  */
+
+static char *
+scan_partial_symbols (char *info_ptr, struct objfile *objfile,
+                     CORE_ADDR *lowpc, CORE_ADDR *highpc,
+                     const struct comp_unit_head *cu_header)
+{
+  bfd *abfd = objfile->obfd;
+  struct partial_die_info pdi;
+
+  /* This function is called after we've read in the comp_unit_die in
+     order to read its children.  We start the nesting level at 1 since
+     we have pushed 1 level down in order to read the comp unit's children.
+     The comp unit itself is at level 0, so we stop reading when we pop
+     back to that level. */
+
+  int nesting_level = 1;
+
+  *lowpc = ((CORE_ADDR) -1);
+  *highpc = ((CORE_ADDR) 0);
+
+  while (nesting_level)
+    {
+      info_ptr = read_partial_die (&pdi, abfd, info_ptr, cu_header);
+
+      if (pdi.name)
+       {
+         switch (pdi.tag)
+           {
+           case DW_TAG_subprogram:
+             if (pdi.has_pc_info)
+               {
+                 if (pdi.lowpc < *lowpc)
+                   {
+                     *lowpc = pdi.lowpc;
+                   }
+                 if (pdi.highpc > *highpc)
+                   {
+                     *highpc = pdi.highpc;
+                   }
+                 if ((pdi.is_external || nesting_level == 1)
+                     && !pdi.is_declaration)
+                   {
+                     add_partial_symbol (&pdi, objfile, cu_header);
+                   }
+               }
+             break;
+           case DW_TAG_variable:
+           case DW_TAG_typedef:
+           case DW_TAG_class_type:
+           case DW_TAG_structure_type:
+           case DW_TAG_union_type:
+           case DW_TAG_enumeration_type:
+             if ((pdi.is_external || nesting_level == 1)
+                 && !pdi.is_declaration)
+               {
+                 add_partial_symbol (&pdi, objfile, cu_header);
+               }
+             break;
+           case DW_TAG_enumerator:
+             /* File scope enumerators are added to the partial symbol
+                table.  */
+             if (nesting_level == 2)
+               add_partial_symbol (&pdi, objfile, cu_header);
+             break;
+           case DW_TAG_base_type:
+             /* File scope base type definitions are added to the partial
+                symbol table.  */
+             if (nesting_level == 1)
+               add_partial_symbol (&pdi, objfile, cu_header);
+             break;
+           default:
+             break;
+           }
+       }
+
+      /* If the die has a sibling, skip to the sibling.
+         Do not skip enumeration types, we want to record their
+         enumerators.  */
+      if (pdi.sibling && pdi.tag != DW_TAG_enumeration_type)
+       {
+         info_ptr = pdi.sibling;
+       }
+      else if (pdi.has_children)
+       {
+         /* Die has children, but the optional DW_AT_sibling attribute
+            is missing.  */
+         nesting_level++;
+       }
+
+      if (pdi.tag == 0)
+       {
+         nesting_level--;
+       }
+    }
+
+  /* If we didn't find a lowpc, set it to highpc to avoid complaints
+     from `maint check'.  */
+  if (*lowpc == ((CORE_ADDR) -1))
+    *lowpc = *highpc;
+  return info_ptr;
+}
+
+static void
+add_partial_symbol (struct partial_die_info *pdi, struct objfile *objfile,
+                   const struct comp_unit_head *cu_header)
+{
+  CORE_ADDR addr = 0;
+
+  switch (pdi->tag)
+    {
+    case DW_TAG_subprogram:
+      if (pdi->is_external)
+       {
+         /*prim_record_minimal_symbol (pdi->name, pdi->lowpc + baseaddr,
+            mst_text, objfile); */
+         add_psymbol_to_list (pdi->name, strlen (pdi->name),
+                              VAR_NAMESPACE, LOC_BLOCK,
+                              &objfile->global_psymbols,
+                           0, pdi->lowpc + baseaddr, cu_language, objfile);
+       }
+      else
+       {
+         /*prim_record_minimal_symbol (pdi->name, pdi->lowpc + baseaddr,
+            mst_file_text, objfile); */
+         add_psymbol_to_list (pdi->name, strlen (pdi->name),
+                              VAR_NAMESPACE, LOC_BLOCK,
+                              &objfile->static_psymbols,
+                           0, pdi->lowpc + baseaddr, cu_language, objfile);
+       }
+      break;
+    case DW_TAG_variable:
+      if (pdi->is_external)
+       {
+         /* Global Variable.
+            Don't enter into the minimal symbol tables as there is
+            a minimal symbol table entry from the ELF symbols already.
+            Enter into partial symbol table if it has a location
+            descriptor or a type.
+            If the location descriptor is missing, new_symbol will create
+            a LOC_UNRESOLVED symbol, the address of the variable will then
+            be determined from the minimal symbol table whenever the variable
+            is referenced.
+            The address for the partial symbol table entry is not
+            used by GDB, but it comes in handy for debugging partial symbol
+            table building.  */
+
+         if (pdi->locdesc)
+           addr = decode_locdesc (pdi->locdesc, objfile, cu_header);
+         if (pdi->locdesc || pdi->has_type)
+           add_psymbol_to_list (pdi->name, strlen (pdi->name),
+                                VAR_NAMESPACE, LOC_STATIC,
+                                &objfile->global_psymbols,
+                                0, addr + baseaddr, cu_language, objfile);
+       }
+      else
+       {
+         /* Static Variable. Skip symbols without location descriptors.  */
+         if (pdi->locdesc == NULL)
+           return;
+         addr = decode_locdesc (pdi->locdesc, objfile, cu_header);
+         /*prim_record_minimal_symbol (pdi->name, addr + baseaddr,
+            mst_file_data, objfile); */
+         add_psymbol_to_list (pdi->name, strlen (pdi->name),
+                              VAR_NAMESPACE, LOC_STATIC,
+                              &objfile->static_psymbols,
+                              0, addr + baseaddr, cu_language, objfile);
+       }
+      break;
+    case DW_TAG_typedef:
+    case DW_TAG_base_type:
+      add_psymbol_to_list (pdi->name, strlen (pdi->name),
+                          VAR_NAMESPACE, LOC_TYPEDEF,
+                          &objfile->static_psymbols,
+                          0, (CORE_ADDR) 0, cu_language, objfile);
+      break;
+    case DW_TAG_class_type:
+    case DW_TAG_structure_type:
+    case DW_TAG_union_type:
+    case DW_TAG_enumeration_type:
+      /* Skip aggregate types without children, these are external
+         references.  */
+      if (pdi->has_children == 0)
+       return;
+      add_psymbol_to_list (pdi->name, strlen (pdi->name),
+                          STRUCT_NAMESPACE, LOC_TYPEDEF,
+                          &objfile->static_psymbols,
+                          0, (CORE_ADDR) 0, cu_language, objfile);
+
+      if (cu_language == language_cplus)
+       {
+         /* For C++, these implicitly act as typedefs as well. */
+         add_psymbol_to_list (pdi->name, strlen (pdi->name),
+                              VAR_NAMESPACE, LOC_TYPEDEF,
+                              &objfile->static_psymbols,
+                              0, (CORE_ADDR) 0, cu_language, objfile);
+       }
+      break;
+    case DW_TAG_enumerator:
+      add_psymbol_to_list (pdi->name, strlen (pdi->name),
+                          VAR_NAMESPACE, LOC_CONST,
+                          &objfile->static_psymbols,
+                          0, (CORE_ADDR) 0, cu_language, objfile);
+      break;
+    default:
+      break;
+    }
+}
+
+/* Expand this partial symbol table into a full symbol table.  */
+
+static void
+dwarf2_psymtab_to_symtab (struct partial_symtab *pst)
+{
+  /* FIXME: This is barely more than a stub.  */
+  if (pst != NULL)
+    {
+      if (pst->readin)
+       {
+         warning ("bug: psymtab for %s is already read in.", pst->filename);
+       }
+      else
+       {
+         if (info_verbose)
+           {
+             printf_filtered ("Reading in symbols for %s...", pst->filename);
+             gdb_flush (gdb_stdout);
+           }
+
+         psymtab_to_symtab_1 (pst);
+
+         /* Finish up the debug error message.  */
+         if (info_verbose)
+           printf_filtered ("done.\n");
+       }
+    }
+}
+
+static void
+psymtab_to_symtab_1 (struct partial_symtab *pst)
+{
+  struct objfile *objfile = pst->objfile;
+  bfd *abfd = objfile->obfd;
+  struct comp_unit_head cu_header;
+  struct die_info *dies;
+  unsigned long offset;
+  CORE_ADDR lowpc, highpc;
+  struct die_info *child_die;
+  char *info_ptr;
+  struct symtab *symtab;
+  struct cleanup *back_to;
+
+  /* Set local variables from the partial symbol table info.  */
+  offset = DWARF_INFO_OFFSET (pst);
+  dwarf_info_buffer = DWARF_INFO_BUFFER (pst);
+  dwarf_abbrev_buffer = DWARF_ABBREV_BUFFER (pst);
+  dwarf_abbrev_size = DWARF_ABBREV_SIZE (pst);
+  dwarf_line_buffer = DWARF_LINE_BUFFER (pst);
+  dwarf_line_size = DWARF_LINE_SIZE (pst);
+  dwarf_str_buffer = DWARF_STR_BUFFER (pst);
+  dwarf_str_size = DWARF_STR_SIZE (pst);
+  dwarf_macinfo_buffer = DWARF_MACINFO_BUFFER (pst);
+  dwarf_macinfo_size = DWARF_MACINFO_SIZE (pst);
+  baseaddr = ANOFFSET (pst->section_offsets, SECT_OFF_TEXT (objfile));
+  cu_header_offset = offset;
+  info_ptr = dwarf_info_buffer + offset;
+
+  obstack_init (&dwarf2_tmp_obstack);
+  back_to = make_cleanup (dwarf2_free_tmp_obstack, NULL);
+
+  buildsym_init ();
+  make_cleanup (really_free_pendings, NULL);
+
+  /* read in the comp_unit header  */
+  info_ptr = read_comp_unit_head (&cu_header, info_ptr, abfd);
+
+  /* Read the abbrevs for this compilation unit  */
+  dwarf2_read_abbrevs (abfd, cu_header.abbrev_offset);
+  make_cleanup (dwarf2_empty_abbrev_table, NULL);
+
+  dies = read_comp_unit (info_ptr, abfd, &cu_header);
+
+  make_cleanup_free_die_list (dies);
+
+  /* Do line number decoding in read_file_scope () */
+  process_die (dies, objfile, &cu_header);
+
+  if (!dwarf2_get_pc_bounds (dies, &lowpc, &highpc, objfile))
+    {
+      /* Some compilers don't define a DW_AT_high_pc attribute for
+         the compilation unit.   If the DW_AT_high_pc is missing,
+         synthesize it, by scanning the DIE's below the compilation unit.  */
+      highpc = 0;
+      if (dies->has_children)
+       {
+         child_die = dies->next;
+         while (child_die && child_die->tag)
+           {
+             if (child_die->tag == DW_TAG_subprogram)
+               {
+                 CORE_ADDR low, high;
+
+                 if (dwarf2_get_pc_bounds (child_die, &low, &high, objfile))
+                   {
+                     highpc = max (highpc, high);
+                   }
+               }
+             child_die = sibling_die (child_die);
+           }
+       }
+    }
+  symtab = end_symtab (highpc + baseaddr, objfile, SECT_OFF_TEXT (objfile));
+
+  /* Set symtab language to language from DW_AT_language.
+     If the compilation is from a C file generated by language preprocessors,
+     do not set the language if it was already deduced by start_subfile.  */
+  if (symtab != NULL
+      && !(cu_language == language_c && symtab->language != language_c))
+    {
+      symtab->language = cu_language;
+    }
+  pst->symtab = symtab;
+  pst->readin = 1;
+  sort_symtab_syms (pst->symtab);
+
+  do_cleanups (back_to);
+}
+
+/* Process a die and its children.  */
+
+static void
+process_die (struct die_info *die, struct objfile *objfile,
+            const struct comp_unit_head *cu_header)
+{
+  switch (die->tag)
+    {
+    case DW_TAG_padding:
+      break;
+    case DW_TAG_compile_unit:
+      read_file_scope (die, objfile, cu_header);
+      break;
+    case DW_TAG_subprogram:
+      read_subroutine_type (die, objfile, cu_header);
+      read_func_scope (die, objfile, cu_header);
+      break;
+    case DW_TAG_inlined_subroutine:
+      /* FIXME:  These are ignored for now.
+         They could be used to set breakpoints on all inlined instances
+         of a function and make GDB `next' properly over inlined functions.  */
+      break;
+    case DW_TAG_lexical_block:
+      read_lexical_block_scope (die, objfile, cu_header);
+      break;
+    case DW_TAG_class_type:
+    case DW_TAG_structure_type:
+    case DW_TAG_union_type:
+      read_structure_scope (die, objfile, cu_header);
+      break;
+    case DW_TAG_enumeration_type:
+      read_enumeration (die, objfile, cu_header);
+      break;
+    case DW_TAG_subroutine_type:
+      read_subroutine_type (die, objfile, cu_header);
+      break;
+    case DW_TAG_array_type:
+      read_array_type (die, objfile, cu_header);
+      break;
+    case DW_TAG_pointer_type:
+      read_tag_pointer_type (die, objfile, cu_header);
+      break;
+    case DW_TAG_ptr_to_member_type:
+      read_tag_ptr_to_member_type (die, objfile, cu_header);
+      break;
+    case DW_TAG_reference_type:
+      read_tag_reference_type (die, objfile, cu_header);
+      break;
+    case DW_TAG_string_type:
+      read_tag_string_type (die, objfile);
+      break;
+    case DW_TAG_base_type:
+      read_base_type (die, objfile);
+      if (dwarf_attr (die, DW_AT_name))
+       {
+         /* Add a typedef symbol for the base type definition.  */
+         new_symbol (die, die->type, objfile, cu_header);
+       }
+      break;
+    case DW_TAG_common_block:
+      read_common_block (die, objfile, cu_header);
+      break;
+    case DW_TAG_common_inclusion:
+      break;
+    default:
+      new_symbol (die, NULL, objfile, cu_header);
+      break;
+    }
+}
+
+static void
+initialize_cu_func_list (void)
+{
+  cu_first_fn = cu_last_fn = cu_cached_fn = NULL;
+}
+
+static void
+read_file_scope (struct die_info *die, struct objfile *objfile,
+                const struct comp_unit_head *cu_header)
+{
+  struct cleanup *back_to = make_cleanup (null_cleanup, 0);
+  CORE_ADDR lowpc = ((CORE_ADDR) -1);
+  CORE_ADDR highpc = ((CORE_ADDR) 0);
+  struct attribute *attr;
+  char *name = "<unknown>";
+  char *comp_dir = NULL;
+  struct die_info *child_die;
+  bfd *abfd = objfile->obfd;
+  struct line_header *line_header = 0;
+
+  if (!dwarf2_get_pc_bounds (die, &lowpc, &highpc, objfile))
+    {
+      if (die->has_children)
+       {
+         child_die = die->next;
+         while (child_die && child_die->tag)
+           {
+             if (child_die->tag == DW_TAG_subprogram)
+               {
+                 CORE_ADDR low, high;
+
+                 if (dwarf2_get_pc_bounds (child_die, &low, &high, objfile))
+                   {
+                     lowpc = min (lowpc, low);
+                     highpc = max (highpc, high);
+                   }
+               }
+             child_die = sibling_die (child_die);
+           }
+       }
+    }
+
+  /* If we didn't find a lowpc, set it to highpc to avoid complaints
+     from finish_block.  */
+  if (lowpc == ((CORE_ADDR) -1))
+    lowpc = highpc;
+  lowpc += baseaddr;
+  highpc += baseaddr;
+
+  attr = dwarf_attr (die, DW_AT_name);
+  if (attr)
+    {
+      name = DW_STRING (attr);
+    }
+  attr = dwarf_attr (die, DW_AT_comp_dir);
+  if (attr)
+    {
+      comp_dir = DW_STRING (attr);
+      if (comp_dir)
+       {
+         /* Irix 6.2 native cc prepends <machine>.: to the compilation
+            directory, get rid of it.  */
+         char *cp = strchr (comp_dir, ':');
+
+         if (cp && cp != comp_dir && cp[-1] == '.' && cp[1] == '/')
+           comp_dir = cp + 1;
+       }
+    }
+
+  if (objfile->ei.entry_point >= lowpc &&
+      objfile->ei.entry_point < highpc)
+    {
+      objfile->ei.entry_file_lowpc = lowpc;
+      objfile->ei.entry_file_highpc = highpc;
+    }
+
+  attr = dwarf_attr (die, DW_AT_language);
+  if (attr)
+    {
+      set_cu_language (DW_UNSND (attr));
+    }
+
+  /* We assume that we're processing GCC output. */
+  processing_gcc_compilation = 2;
+#if 0
+  /* FIXME:Do something here.  */
+  if (dip->at_producer != NULL)
+    {
+      handle_producer (dip->at_producer);
+    }
+#endif
+
+  /* The compilation unit may be in a different language or objfile,
+     zero out all remembered fundamental types.  */
+  memset (ftypes, 0, FT_NUM_MEMBERS * sizeof (struct type *));
+
+  start_symtab (name, comp_dir, lowpc);
+  record_debugformat ("DWARF 2");
+
+  initialize_cu_func_list ();
+
+  /* Process all dies in compilation unit.  */
+  if (die->has_children)
+    {
+      child_die = die->next;
+      while (child_die && child_die->tag)
+       {
+         process_die (child_die, objfile, cu_header);
+         child_die = sibling_die (child_die);
+       }
+    }
+
+  /* Decode line number information if present.  */
+  attr = dwarf_attr (die, DW_AT_stmt_list);
+  if (attr)
+    {
+      unsigned int line_offset = DW_UNSND (attr);
+      line_header = dwarf_decode_line_header (line_offset,
+                                              abfd, cu_header);
+      if (line_header)
+        {
+          make_cleanup ((make_cleanup_ftype *) free_line_header,
+                        (void *) line_header);
+          dwarf_decode_lines (line_header, comp_dir, abfd, cu_header);
+        }
+    }
+
+  /* Decode macro information, if present.  Dwarf 2 macro information
+     refers to information in the line number info statement program
+     header, so we can only read it if we've read the header
+     successfully.  */
+  attr = dwarf_attr (die, DW_AT_macro_info);
+  if (attr && line_header)
+    {
+      unsigned int macro_offset = DW_UNSND (attr);
+      dwarf_decode_macros (line_header, macro_offset,
+                           comp_dir, abfd, cu_header, objfile);
+    }
+  do_cleanups (back_to);
+}
+
+static void
+add_to_cu_func_list (const char *name, CORE_ADDR lowpc, CORE_ADDR highpc)
+{
+  struct function_range *thisfn;
+
+  thisfn = (struct function_range *)
+    obstack_alloc (&dwarf2_tmp_obstack, sizeof (struct function_range));
+  thisfn->name = name;
+  thisfn->lowpc = lowpc;
+  thisfn->highpc = highpc;
+  thisfn->seen_line = 0;
+  thisfn->next = NULL;
+
+  if (cu_last_fn == NULL)
+      cu_first_fn = thisfn;
+  else
+      cu_last_fn->next = thisfn;
+
+  cu_last_fn = thisfn;
+}
+
+static void
+read_func_scope (struct die_info *die, struct objfile *objfile,
+                const struct comp_unit_head *cu_header)
+{
+  register struct context_stack *new;
+  CORE_ADDR lowpc;
+  CORE_ADDR highpc;
+  struct die_info *child_die;
+  struct attribute *attr;
+  char *name;
+
+  name = dwarf2_linkage_name (die);
+
+  /* Ignore functions with missing or empty names and functions with
+     missing or invalid low and high pc attributes.  */
+  if (name == NULL || !dwarf2_get_pc_bounds (die, &lowpc, &highpc, objfile))
+    return;
+
+  lowpc += baseaddr;
+  highpc += baseaddr;
+
+  /* Record the function range for dwarf_decode_lines.  */
+  add_to_cu_func_list (name, lowpc, highpc);
+
+  if (objfile->ei.entry_point >= lowpc &&
+      objfile->ei.entry_point < highpc)
+    {
+      objfile->ei.entry_func_lowpc = lowpc;
+      objfile->ei.entry_func_highpc = highpc;
+    }
+
+  /* Decode DW_AT_frame_base location descriptor if present, keep result
+     for DW_OP_fbreg operands in decode_locdesc.  */
+  frame_base_reg = -1;
+  frame_base_offset = 0;
+  attr = dwarf_attr (die, DW_AT_frame_base);
+  if (attr)
+    {
+      CORE_ADDR addr;
+
+      /* Support the .debug_loc offsets */
+      if (attr_form_is_block (attr))
+        {
+          addr = decode_locdesc (DW_BLOCK (attr), objfile, cu_header);
+        }
+      else if (attr->form == DW_FORM_data4 || attr->form == DW_FORM_data8)
+        {
+          complain (&dwarf2_complex_location_expr);
+          addr = 0;
+        }
+      else
+        {
+          complain (&dwarf2_invalid_attrib_class, "DW_AT_frame_base", name);
+          addr = 0;
+        }
+    
+      if (isderef)
+       complain (&dwarf2_unsupported_at_frame_base, name);
+      else if (isreg)
+       frame_base_reg = addr;
+      else if (offreg)
+       {
+         frame_base_reg = basereg;
+         frame_base_offset = addr;
+       }
+      else
+       complain (&dwarf2_unsupported_at_frame_base, name);
+    }
+
+  new = push_context (0, lowpc);
+  new->name = new_symbol (die, die->type, objfile, cu_header);
+  list_in_scope = &local_symbols;
+
+  if (die->has_children)
+    {
+      child_die = die->next;
+      while (child_die && child_die->tag)
+       {
+         process_die (child_die, objfile, cu_header);
+         child_die = sibling_die (child_die);
+       }
+    }
+
+  new = pop_context ();
+  /* Make a block for the local symbols within.  */
+  finish_block (new->name, &local_symbols, new->old_blocks,
+               lowpc, highpc, objfile);
+  list_in_scope = &file_symbols;
+}
+
+/* Process all the DIES contained within a lexical block scope.  Start
+   a new scope, process the dies, and then close the scope.  */
+
+static void
+read_lexical_block_scope (struct die_info *die, struct objfile *objfile,
+                         const struct comp_unit_head *cu_header)
+{
+  register struct context_stack *new;
+  CORE_ADDR lowpc, highpc;
+  struct die_info *child_die;
+
+  /* Ignore blocks with missing or invalid low and high pc attributes.  */
+  if (!dwarf2_get_pc_bounds (die, &lowpc, &highpc, objfile))
+    return;
+  lowpc += baseaddr;
+  highpc += baseaddr;
+
+  push_context (0, lowpc);
+  if (die->has_children)
+    {
+      child_die = die->next;
+      while (child_die && child_die->tag)
+       {
+         process_die (child_die, objfile, cu_header);
+         child_die = sibling_die (child_die);
+       }
+    }
+  new = pop_context ();
+
+  if (local_symbols != NULL)
+    {
+      finish_block (0, &local_symbols, new->old_blocks, new->start_addr,
+                   highpc, objfile);
+    }
+  local_symbols = new->locals;
+}
+
+/* Get low and high pc attributes from a die.
+   Return 1 if the attributes are present and valid, otherwise, return 0.  */
+
+static int
+dwarf2_get_pc_bounds (struct die_info *die, CORE_ADDR *lowpc, CORE_ADDR *highpc,
+                     struct objfile *objfile)
+{
+  struct attribute *attr;
+  CORE_ADDR low;
+  CORE_ADDR high;
+
+  attr = dwarf_attr (die, DW_AT_low_pc);
+  if (attr)
+    low = DW_ADDR (attr);
+  else
+    return 0;
+  attr = dwarf_attr (die, DW_AT_high_pc);
+  if (attr)
+    high = DW_ADDR (attr);
+  else
+    return 0;
+
+  if (high < low)
+    return 0;
+
+  /* When using the GNU linker, .gnu.linkonce. sections are used to
+     eliminate duplicate copies of functions and vtables and such.
+     The linker will arbitrarily choose one and discard the others.
+     The AT_*_pc values for such functions refer to local labels in
+     these sections.  If the section from that file was discarded, the
+     labels are not in the output, so the relocs get a value of 0.
+     If this is a discarded function, mark the pc bounds as invalid,
+     so that GDB will ignore it.  */
+  if (low == 0 && (bfd_get_file_flags (objfile->obfd) & HAS_RELOC) == 0)
+    return 0;
+
+  *lowpc = low;
+  *highpc = high;
+  return 1;
+}
+
+/* Add an aggregate field to the field list.  */
+
+static void
+dwarf2_add_field (struct field_info *fip, struct die_info *die,
+                 struct objfile *objfile,
+                 const struct comp_unit_head *cu_header)
+{
+  struct nextfield *new_field;
+  struct attribute *attr;
+  struct field *fp;
+  char *fieldname = "";
+
+  /* Allocate a new field list entry and link it in.  */
+  new_field = (struct nextfield *) xmalloc (sizeof (struct nextfield));
+  make_cleanup (xfree, new_field);
+  memset (new_field, 0, sizeof (struct nextfield));
+  new_field->next = fip->fields;
+  fip->fields = new_field;
+  fip->nfields++;
+
+  /* Handle accessibility and virtuality of field.
+     The default accessibility for members is public, the default
+     accessibility for inheritance is private.  */
+  if (die->tag != DW_TAG_inheritance)
+    new_field->accessibility = DW_ACCESS_public;
+  else
+    new_field->accessibility = DW_ACCESS_private;
+  new_field->virtuality = DW_VIRTUALITY_none;
+
+  attr = dwarf_attr (die, DW_AT_accessibility);
+  if (attr)
+    new_field->accessibility = DW_UNSND (attr);
+  if (new_field->accessibility != DW_ACCESS_public)
+    fip->non_public_fields = 1;
+  attr = dwarf_attr (die, DW_AT_virtuality);
+  if (attr)
+    new_field->virtuality = DW_UNSND (attr);
+
+  fp = &new_field->field;
+  if (die->tag == DW_TAG_member)
+    {
+      /* Get type of field.  */
+      fp->type = die_type (die, objfile, cu_header);
+
+      /* Get bit size of field (zero if none).  */
+      attr = dwarf_attr (die, DW_AT_bit_size);
+      if (attr)
+       {
+         FIELD_BITSIZE (*fp) = DW_UNSND (attr);
+       }
+      else
+       {
+         FIELD_BITSIZE (*fp) = 0;
+       }
+
+      /* Get bit offset of field.  */
+      attr = dwarf_attr (die, DW_AT_data_member_location);
+      if (attr)
+       {
+         FIELD_BITPOS (*fp) =
+           decode_locdesc (DW_BLOCK (attr), objfile, cu_header) * bits_per_byte;
+       }
+      else
+       FIELD_BITPOS (*fp) = 0;
+      attr = dwarf_attr (die, DW_AT_bit_offset);
+      if (attr)
+       {
+         if (BITS_BIG_ENDIAN)
+           {
+             /* For big endian bits, the DW_AT_bit_offset gives the
+                additional bit offset from the MSB of the containing
+                anonymous object to the MSB of the field.  We don't
+                have to do anything special since we don't need to
+                know the size of the anonymous object.  */
+             FIELD_BITPOS (*fp) += DW_UNSND (attr);
+           }
+         else
+           {
+             /* For little endian bits, compute the bit offset to the
+                MSB of the anonymous object, subtract off the number of
+                bits from the MSB of the field to the MSB of the
+                object, and then subtract off the number of bits of
+                the field itself.  The result is the bit offset of
+                the LSB of the field.  */
+             int anonymous_size;
+             int bit_offset = DW_UNSND (attr);
+
+             attr = dwarf_attr (die, DW_AT_byte_size);
+             if (attr)
+               {
+                 /* The size of the anonymous object containing
+                    the bit field is explicit, so use the
+                    indicated size (in bytes).  */
+                 anonymous_size = DW_UNSND (attr);
+               }
+             else
+               {
+                 /* The size of the anonymous object containing
+                    the bit field must be inferred from the type
+                    attribute of the data member containing the
+                    bit field.  */
+                 anonymous_size = TYPE_LENGTH (fp->type);
+               }
+             FIELD_BITPOS (*fp) += anonymous_size * bits_per_byte
+               - bit_offset - FIELD_BITSIZE (*fp);
+           }
+       }
+
+      /* Get name of field.  */
+      attr = dwarf_attr (die, DW_AT_name);
+      if (attr && DW_STRING (attr))
+       fieldname = DW_STRING (attr);
+      fp->name = obsavestring (fieldname, strlen (fieldname),
+                              &objfile->type_obstack);
+
+      /* Change accessibility for artificial fields (e.g. virtual table
+         pointer or virtual base class pointer) to private.  */
+      if (dwarf_attr (die, DW_AT_artificial))
+       {
+         new_field->accessibility = DW_ACCESS_private;
+         fip->non_public_fields = 1;
+       }
+    }
+  else if (die->tag == DW_TAG_variable)
+    {
+      char *physname;
+
+      /* C++ static member.
+        Get name of field.  */
+      attr = dwarf_attr (die, DW_AT_name);
+      if (attr && DW_STRING (attr))
+       fieldname = DW_STRING (attr);
+      else
+       return;
+
+      /* Get physical name.  */
+      physname = dwarf2_linkage_name (die);
+
+      SET_FIELD_PHYSNAME (*fp, obsavestring (physname, strlen (physname),
+                                            &objfile->type_obstack));
+      FIELD_TYPE (*fp) = die_type (die, objfile, cu_header);
+      FIELD_NAME (*fp) = obsavestring (fieldname, strlen (fieldname),
+                                      &objfile->type_obstack);
+    }
+  else if (die->tag == DW_TAG_inheritance)
+    {
+      /* C++ base class field.  */
+      attr = dwarf_attr (die, DW_AT_data_member_location);
+      if (attr)
+       FIELD_BITPOS (*fp) = (decode_locdesc (DW_BLOCK (attr), objfile, cu_header)
+                             * bits_per_byte);
+      FIELD_BITSIZE (*fp) = 0;
+      FIELD_TYPE (*fp) = die_type (die, objfile, cu_header);
+      FIELD_NAME (*fp) = type_name_no_tag (fp->type);
+      fip->nbaseclasses++;
+    }
+}
+
+/* Create the vector of fields, and attach it to the type.  */
+
+static void
+dwarf2_attach_fields_to_type (struct field_info *fip, struct type *type,
+                             struct objfile *objfile)
+{
+  int nfields = fip->nfields;
+
+  /* Record the field count, allocate space for the array of fields,
+     and create blank accessibility bitfields if necessary.  */
+  TYPE_NFIELDS (type) = nfields;
+  TYPE_FIELDS (type) = (struct field *)
+    TYPE_ALLOC (type, sizeof (struct field) * nfields);
+  memset (TYPE_FIELDS (type), 0, sizeof (struct field) * nfields);
+
+  if (fip->non_public_fields)
+    {
+      ALLOCATE_CPLUS_STRUCT_TYPE (type);
+
+      TYPE_FIELD_PRIVATE_BITS (type) =
+       (B_TYPE *) TYPE_ALLOC (type, B_BYTES (nfields));
+      B_CLRALL (TYPE_FIELD_PRIVATE_BITS (type), nfields);
+
+      TYPE_FIELD_PROTECTED_BITS (type) =
+       (B_TYPE *) TYPE_ALLOC (type, B_BYTES (nfields));
+      B_CLRALL (TYPE_FIELD_PROTECTED_BITS (type), nfields);
+
+      TYPE_FIELD_IGNORE_BITS (type) =
+       (B_TYPE *) TYPE_ALLOC (type, B_BYTES (nfields));
+      B_CLRALL (TYPE_FIELD_IGNORE_BITS (type), nfields);
+    }
+
+  /* If the type has baseclasses, allocate and clear a bit vector for
+     TYPE_FIELD_VIRTUAL_BITS.  */
+  if (fip->nbaseclasses)
+    {
+      int num_bytes = B_BYTES (fip->nbaseclasses);
+      char *pointer;
+
+      ALLOCATE_CPLUS_STRUCT_TYPE (type);
+      pointer = (char *) TYPE_ALLOC (type, num_bytes);
+      TYPE_FIELD_VIRTUAL_BITS (type) = (B_TYPE *) pointer;
+      B_CLRALL (TYPE_FIELD_VIRTUAL_BITS (type), fip->nbaseclasses);
+      TYPE_N_BASECLASSES (type) = fip->nbaseclasses;
+    }
+
+  /* Copy the saved-up fields into the field vector.  Start from the head
+     of the list, adding to the tail of the field array, so that they end
+     up in the same order in the array in which they were added to the list.  */
+  while (nfields-- > 0)
+    {
+      TYPE_FIELD (type, nfields) = fip->fields->field;
+      switch (fip->fields->accessibility)
+       {
+       case DW_ACCESS_private:
+         SET_TYPE_FIELD_PRIVATE (type, nfields);
+         break;
+
+       case DW_ACCESS_protected:
+         SET_TYPE_FIELD_PROTECTED (type, nfields);
+         break;
+
+       case DW_ACCESS_public:
+         break;
+
+       default:
+         /* Unknown accessibility.  Complain and treat it as public.  */
+         {
+           complain (&dwarf2_unsupported_accessibility,
+                     fip->fields->accessibility);
+         }
+         break;
+       }
+      if (nfields < fip->nbaseclasses)
+       {
+         switch (fip->fields->virtuality)
+           {
+           case DW_VIRTUALITY_virtual:
+           case DW_VIRTUALITY_pure_virtual:
+             SET_TYPE_FIELD_VIRTUAL (type, nfields);
+             break;
+           }
+       }
+      fip->fields = fip->fields->next;
+    }
+}
+
+/* Add a member function to the proper fieldlist.  */
+
+static void
+dwarf2_add_member_fn (struct field_info *fip, struct die_info *die,
+                     struct type *type, struct objfile *objfile,
+                     const struct comp_unit_head *cu_header)
+{
+  struct attribute *attr;
+  struct fnfieldlist *flp;
+  int i;
+  struct fn_field *fnp;
+  char *fieldname;
+  char *physname;
+  struct nextfnfield *new_fnfield;
+
+  /* Get name of member function.  */
+  attr = dwarf_attr (die, DW_AT_name);
+  if (attr && DW_STRING (attr))
+    fieldname = DW_STRING (attr);
+  else
+    return;
+
+  /* Get the mangled name.  */
+  physname = dwarf2_linkage_name (die);
+
+  /* Look up member function name in fieldlist.  */
+  for (i = 0; i < fip->nfnfields; i++)
+    {
+      if (STREQ (fip->fnfieldlists[i].name, fieldname))
+       break;
+    }
+
+  /* Create new list element if necessary.  */
+  if (i < fip->nfnfields)
+    flp = &fip->fnfieldlists[i];
+  else
+    {
+      if ((fip->nfnfields % DW_FIELD_ALLOC_CHUNK) == 0)
+       {
+         fip->fnfieldlists = (struct fnfieldlist *)
+           xrealloc (fip->fnfieldlists,
+                     (fip->nfnfields + DW_FIELD_ALLOC_CHUNK)
+                     * sizeof (struct fnfieldlist));
+         if (fip->nfnfields == 0)
+           make_cleanup (free_current_contents, &fip->fnfieldlists);
+       }
+      flp = &fip->fnfieldlists[fip->nfnfields];
+      flp->name = fieldname;
+      flp->length = 0;
+      flp->head = NULL;
+      fip->nfnfields++;
+    }
+
+  /* Create a new member function field and chain it to the field list
+     entry. */
+  new_fnfield = (struct nextfnfield *) xmalloc (sizeof (struct nextfnfield));
+  make_cleanup (xfree, new_fnfield);
+  memset (new_fnfield, 0, sizeof (struct nextfnfield));
+  new_fnfield->next = flp->head;
+  flp->head = new_fnfield;
+  flp->length++;
+
+  /* Fill in the member function field info.  */
+  fnp = &new_fnfield->fnfield;
+  fnp->physname = obsavestring (physname, strlen (physname),
+                               &objfile->type_obstack);
+  fnp->type = alloc_type (objfile);
+  if (die->type && TYPE_CODE (die->type) == TYPE_CODE_FUNC)
+    {
+      struct type *return_type = TYPE_TARGET_TYPE (die->type);
+      int nparams = TYPE_NFIELDS (die->type);
+
+      /* TYPE is the domain of this method, and DIE->TYPE is the type
+          of the method itself (TYPE_CODE_METHOD).  */
+      smash_to_method_type (fnp->type, type,
+                           TYPE_TARGET_TYPE (die->type),
+                           TYPE_FIELDS (die->type),
+                           TYPE_NFIELDS (die->type),
+                           TYPE_VARARGS (die->type));
+
+      /* Handle static member functions.
+         Dwarf2 has no clean way to discern C++ static and non-static
+         member functions. G++ helps GDB by marking the first
+         parameter for non-static member functions (which is the
+         this pointer) as artificial. We obtain this information
+         from read_subroutine_type via TYPE_FIELD_ARTIFICIAL.  */
+      if (nparams == 0 || TYPE_FIELD_ARTIFICIAL (die->type, 0) == 0)
+       fnp->voffset = VOFFSET_STATIC;
+    }
+  else
+    complain (&dwarf2_missing_member_fn_type_complaint, physname);
+
+  /* Get fcontext from DW_AT_containing_type if present.  */
+  if (dwarf_attr (die, DW_AT_containing_type) != NULL)
+    fnp->fcontext = die_containing_type (die, objfile, cu_header);
+
+  /* dwarf2 doesn't have stubbed physical names, so the setting of is_const
+     and is_volatile is irrelevant, as it is needed by gdb_mangle_name only.  */
+
+  /* Get accessibility.  */
+  attr = dwarf_attr (die, DW_AT_accessibility);
+  if (attr)
+    {
+      switch (DW_UNSND (attr))
+       {
+       case DW_ACCESS_private:
+         fnp->is_private = 1;
+         break;
+       case DW_ACCESS_protected:
+         fnp->is_protected = 1;
+         break;
+       }
+    }
+
+  /* Check for artificial methods.  */
+  attr = dwarf_attr (die, DW_AT_artificial);
+  if (attr && DW_UNSND (attr) != 0)
+    fnp->is_artificial = 1;
+
+  /* Get index in virtual function table if it is a virtual member function.  */
+  attr = dwarf_attr (die, DW_AT_vtable_elem_location);
+  if (attr)
+    {
+      /* Support the .debug_loc offsets */
+      if (attr_form_is_block (attr))
+        {
+          fnp->voffset = decode_locdesc (DW_BLOCK (attr), objfile, cu_header) + 2;
+        }
+      else if (attr->form == DW_FORM_data4 || attr->form == DW_FORM_data8)
+        {
+          complain (&dwarf2_complex_location_expr);
+        }
+      else
+        {
+          complain (&dwarf2_invalid_attrib_class, "DW_AT_vtable_elem_location",
+                    fieldname);
+        }
+   }
+}
+
+/* Create the vector of member function fields, and attach it to the type.  */
+
+static void
+dwarf2_attach_fn_fields_to_type (struct field_info *fip, struct type *type,
+                                struct objfile *objfile)
+{
+  struct fnfieldlist *flp;
+  int total_length = 0;
+  int i;
+
+  ALLOCATE_CPLUS_STRUCT_TYPE (type);
+  TYPE_FN_FIELDLISTS (type) = (struct fn_fieldlist *)
+    TYPE_ALLOC (type, sizeof (struct fn_fieldlist) * fip->nfnfields);
+
+  for (i = 0, flp = fip->fnfieldlists; i < fip->nfnfields; i++, flp++)
+    {
+      struct nextfnfield *nfp = flp->head;
+      struct fn_fieldlist *fn_flp = &TYPE_FN_FIELDLIST (type, i);
+      int k;
+
+      TYPE_FN_FIELDLIST_NAME (type, i) = flp->name;
+      TYPE_FN_FIELDLIST_LENGTH (type, i) = flp->length;
+      fn_flp->fn_fields = (struct fn_field *)
+       TYPE_ALLOC (type, sizeof (struct fn_field) * flp->length);
+      for (k = flp->length; (k--, nfp); nfp = nfp->next)
+       fn_flp->fn_fields[k] = nfp->fnfield;
+
+      total_length += flp->length;
+    }
+
+  TYPE_NFN_FIELDS (type) = fip->nfnfields;
+  TYPE_NFN_FIELDS_TOTAL (type) = total_length;
+}
+
+/* Called when we find the DIE that starts a structure or union scope
+   (definition) to process all dies that define the members of the
+   structure or union.
+
+   NOTE: we need to call struct_type regardless of whether or not the
+   DIE has an at_name attribute, since it might be an anonymous
+   structure or union.  This gets the type entered into our set of
+   user defined types.
+
+   However, if the structure is incomplete (an opaque struct/union)
+   then suppress creating a symbol table entry for it since gdb only
+   wants to find the one with the complete definition.  Note that if
+   it is complete, we just call new_symbol, which does it's own
+   checking about whether the struct/union is anonymous or not (and
+   suppresses creating a symbol table entry itself).  */
+
+static void
+read_structure_scope (struct die_info *die, struct objfile *objfile,
+                     const struct comp_unit_head *cu_header)
+{
+  struct type *type;
+  struct attribute *attr;
+
+  type = alloc_type (objfile);
+
+  INIT_CPLUS_SPECIFIC (type);
+  attr = dwarf_attr (die, DW_AT_name);
+  if (attr && DW_STRING (attr))
+    {
+      TYPE_TAG_NAME (type) = obsavestring (DW_STRING (attr),
+                                          strlen (DW_STRING (attr)),
+                                          &objfile->type_obstack);
+    }
+
+  if (die->tag == DW_TAG_structure_type)
+    {
+      TYPE_CODE (type) = TYPE_CODE_STRUCT;
+    }
+  else if (die->tag == DW_TAG_union_type)
+    {
+      TYPE_CODE (type) = TYPE_CODE_UNION;
+    }
+  else
+    {
+      /* FIXME: TYPE_CODE_CLASS is currently defined to TYPE_CODE_STRUCT
+         in gdbtypes.h.  */
+      TYPE_CODE (type) = TYPE_CODE_CLASS;
+    }
+
+  attr = dwarf_attr (die, DW_AT_byte_size);
+  if (attr)
+    {
+      TYPE_LENGTH (type) = DW_UNSND (attr);
+    }
+  else
+    {
+      TYPE_LENGTH (type) = 0;
+    }
+
+  /* We need to add the type field to the die immediately so we don't
+     infinitely recurse when dealing with pointers to the structure
+     type within the structure itself. */
+  die->type = type;
+
+  if (die->has_children && ! die_is_declaration (die))
+    {
+      struct field_info fi;
+      struct die_info *child_die;
+      struct cleanup *back_to = make_cleanup (null_cleanup, NULL);
+
+      memset (&fi, 0, sizeof (struct field_info));
+
+      child_die = die->next;
+
+      while (child_die && child_die->tag)
+       {
+         if (child_die->tag == DW_TAG_member)
+           {
+             dwarf2_add_field (&fi, child_die, objfile, cu_header);
+           }
+         else if (child_die->tag == DW_TAG_variable)
+           {
+             /* C++ static member.  */
+             dwarf2_add_field (&fi, child_die, objfile, cu_header);
+           }
+         else if (child_die->tag == DW_TAG_subprogram)
+           {
+             /* C++ member function. */
+             process_die (child_die, objfile, cu_header);
+             dwarf2_add_member_fn (&fi, child_die, type, objfile, cu_header);
+           }
+         else if (child_die->tag == DW_TAG_inheritance)
+           {
+             /* C++ base class field.  */
+             dwarf2_add_field (&fi, child_die, objfile, cu_header);
+           }
+         else
+           {
+             process_die (child_die, objfile, cu_header);
+           }
+         child_die = sibling_die (child_die);
+       }
+
+      /* Attach fields and member functions to the type.  */
+      if (fi.nfields)
+       dwarf2_attach_fields_to_type (&fi, type, objfile);
+      if (fi.nfnfields)
+       {
+         dwarf2_attach_fn_fields_to_type (&fi, type, objfile);
+
+         /* Get the type which refers to the base class (possibly this
+            class itself) which contains the vtable pointer for the current
+            class from the DW_AT_containing_type attribute.  */
+
+         if (dwarf_attr (die, DW_AT_containing_type) != NULL)
+           {
+             struct type *t = die_containing_type (die, objfile, cu_header);
+
+             TYPE_VPTR_BASETYPE (type) = t;
+             if (type == t)
+               {
+                 static const char vptr_name[] =
+                 {'_', 'v', 'p', 't', 'r', '\0'};
+                 int i;
+
+                 /* Our own class provides vtbl ptr.  */
+                 for (i = TYPE_NFIELDS (t) - 1;
+                      i >= TYPE_N_BASECLASSES (t);
+                      --i)
+                   {
+                     char *fieldname = TYPE_FIELD_NAME (t, i);
+
+                     if (STREQN (fieldname, vptr_name, strlen (vptr_name) - 1)
+                         && is_cplus_marker (fieldname[strlen (vptr_name)]))
+                       {
+                         TYPE_VPTR_FIELDNO (type) = i;
+                         break;
+                       }
+                   }
+
+                 /* Complain if virtual function table field not found.  */
+                 if (i < TYPE_N_BASECLASSES (t))
+                   complain (&dwarf2_vtbl_not_found_complaint,
+                         TYPE_TAG_NAME (type) ? TYPE_TAG_NAME (type) : "");
+               }
+             else
+               {
+                 TYPE_VPTR_FIELDNO (type) = TYPE_VPTR_FIELDNO (t);
+               }
+           }
+       }
+
+      new_symbol (die, type, objfile, cu_header);
+
+      do_cleanups (back_to);
+    }
+  else
+    {
+      /* No children, must be stub. */
+      TYPE_FLAGS (type) |= TYPE_FLAG_STUB;
+    }
+}
+
+/* Given a pointer to a die which begins an enumeration, process all
+   the dies that define the members of the enumeration.
+
+   This will be much nicer in draft 6 of the DWARF spec when our
+   members will be dies instead squished into the DW_AT_element_list
+   attribute.
+
+   NOTE: We reverse the order of the element list.  */
+
+static void
+read_enumeration (struct die_info *die, struct objfile *objfile,
+                 const struct comp_unit_head *cu_header)
+{
+  struct die_info *child_die;
+  struct type *type;
+  struct field *fields;
+  struct attribute *attr;
+  struct symbol *sym;
+  int num_fields;
+  int unsigned_enum = 1;
+
+  type = alloc_type (objfile);
+
+  TYPE_CODE (type) = TYPE_CODE_ENUM;
+  attr = dwarf_attr (die, DW_AT_name);
+  if (attr && DW_STRING (attr))
+    {
+      TYPE_TAG_NAME (type) = obsavestring (DW_STRING (attr),
+                                          strlen (DW_STRING (attr)),
+                                          &objfile->type_obstack);
+    }
+
+  attr = dwarf_attr (die, DW_AT_byte_size);
+  if (attr)
+    {
+      TYPE_LENGTH (type) = DW_UNSND (attr);
+    }
+  else
+    {
+      TYPE_LENGTH (type) = 0;
+    }
+
+  num_fields = 0;
+  fields = NULL;
+  if (die->has_children)
+    {
+      child_die = die->next;
+      while (child_die && child_die->tag)
+       {
+         if (child_die->tag != DW_TAG_enumerator)
+           {
+             process_die (child_die, objfile, cu_header);
+           }
+         else
+           {
+             attr = dwarf_attr (child_die, DW_AT_name);
+             if (attr)
+               {
+                 sym = new_symbol (child_die, type, objfile, cu_header);
+                 if (SYMBOL_VALUE (sym) < 0)
+                   unsigned_enum = 0;
+
+                 if ((num_fields % DW_FIELD_ALLOC_CHUNK) == 0)
+                   {
+                     fields = (struct field *)
+                       xrealloc (fields,
+                                 (num_fields + DW_FIELD_ALLOC_CHUNK)
+                                 * sizeof (struct field));
+                   }
+
+                 FIELD_NAME (fields[num_fields]) = SYMBOL_NAME (sym);
+                 FIELD_TYPE (fields[num_fields]) = NULL;
+                 FIELD_BITPOS (fields[num_fields]) = SYMBOL_VALUE (sym);
+                 FIELD_BITSIZE (fields[num_fields]) = 0;
+
+                 num_fields++;
+               }
+           }
+
+         child_die = sibling_die (child_die);
+       }
+
+      if (num_fields)
+       {
+         TYPE_NFIELDS (type) = num_fields;
+         TYPE_FIELDS (type) = (struct field *)
+           TYPE_ALLOC (type, sizeof (struct field) * num_fields);
+         memcpy (TYPE_FIELDS (type), fields,
+                 sizeof (struct field) * num_fields);
+         xfree (fields);
+       }
+      if (unsigned_enum)
+       TYPE_FLAGS (type) |= TYPE_FLAG_UNSIGNED;
+    }
+  die->type = type;
+  new_symbol (die, type, objfile, cu_header);
+}
+
+/* Extract all information from a DW_TAG_array_type DIE and put it in
+   the DIE's type field.  For now, this only handles one dimensional
+   arrays.  */
+
+static void
+read_array_type (struct die_info *die, struct objfile *objfile,
+                const struct comp_unit_head *cu_header)
+{
+  struct die_info *child_die;
+  struct type *type = NULL;
+  struct type *element_type, *range_type, *index_type;
+  struct type **range_types = NULL;
+  struct attribute *attr;
+  int ndim = 0;
+  struct cleanup *back_to;
+
+  /* Return if we've already decoded this type. */
+  if (die->type)
+    {
+      return;
+    }
+
+  element_type = die_type (die, objfile, cu_header);
+
+  /* Irix 6.2 native cc creates array types without children for
+     arrays with unspecified length.  */
+  if (die->has_children == 0)
+    {
+      index_type = dwarf2_fundamental_type (objfile, FT_INTEGER);
+      range_type = create_range_type (NULL, index_type, 0, -1);
+      die->type = create_array_type (NULL, element_type, range_type);
+      return;
+    }
+
+  back_to = make_cleanup (null_cleanup, NULL);
+  child_die = die->next;
+  while (child_die && child_die->tag)
+    {
+      if (child_die->tag == DW_TAG_subrange_type)
+       {
+         unsigned int low, high;
+
+         /* Default bounds to an array with unspecified length.  */
+         low = 0;
+         high = -1;
+         if (cu_language == language_fortran)
+           {
+             /* FORTRAN implies a lower bound of 1, if not given.  */
+             low = 1;
+           }
+
+         index_type = die_type (child_die, objfile, cu_header);
+         attr = dwarf_attr (child_die, DW_AT_lower_bound);
+         if (attr)
+           {
+             if (attr->form == DW_FORM_sdata)
+               {
+                 low = DW_SND (attr);
+               }
+             else if (attr->form == DW_FORM_udata
+                      || attr->form == DW_FORM_data1
+                      || attr->form == DW_FORM_data2
+                      || attr->form == DW_FORM_data4
+                      || attr->form == DW_FORM_data8)
+               {
+                 low = DW_UNSND (attr);
+               }
+             else
+               {
+                 complain (&dwarf2_non_const_array_bound_ignored,
+                           dwarf_form_name (attr->form));
+#ifdef FORTRAN_HACK
+                 die->type = lookup_pointer_type (element_type);
+                 return;
+#else
+                 low = 0;
+#endif
+               }
+           }
+         attr = dwarf_attr (child_die, DW_AT_upper_bound);
+         if (attr)
+           {
+             if (attr->form == DW_FORM_sdata)
+               {
+                 high = DW_SND (attr);
+               }
+             else if (attr->form == DW_FORM_udata
+                      || attr->form == DW_FORM_data1
+                      || attr->form == DW_FORM_data2
+                      || attr->form == DW_FORM_data4
+                      || attr->form == DW_FORM_data8)
+               {
+                 high = DW_UNSND (attr);
+               }
+             else if (attr->form == DW_FORM_block1)
+               {
+                 /* GCC encodes arrays with unspecified or dynamic length
+                    with a DW_FORM_block1 attribute.
+                    FIXME: GDB does not yet know how to handle dynamic
+                    arrays properly, treat them as arrays with unspecified
+                    length for now.  */
+                 high = -1;
+               }
+             else
+               {
+                 complain (&dwarf2_non_const_array_bound_ignored,
+                           dwarf_form_name (attr->form));
+#ifdef FORTRAN_HACK
+                 die->type = lookup_pointer_type (element_type);
+                 return;
+#else
+                 high = 1;
+#endif
+               }
+           }
+
+         /* Create a range type and save it for array type creation.  */
+         if ((ndim % DW_FIELD_ALLOC_CHUNK) == 0)
+           {
+             range_types = (struct type **)
+               xrealloc (range_types, (ndim + DW_FIELD_ALLOC_CHUNK)
+                         * sizeof (struct type *));
+             if (ndim == 0)
+               make_cleanup (free_current_contents, &range_types);
+           }
+         range_types[ndim++] = create_range_type (NULL, index_type, low, high);
+       }
+      child_die = sibling_die (child_die);
+    }
+
+  /* Dwarf2 dimensions are output from left to right, create the
+     necessary array types in backwards order.  */
+  type = element_type;
+  while (ndim-- > 0)
+    type = create_array_type (NULL, type, range_types[ndim]);
+
+  /* Understand Dwarf2 support for vector types (like they occur on
+     the PowerPC w/ AltiVec).  Gcc just adds another attribute to the
+     array type.  This is not part of the Dwarf2/3 standard yet, but a
+     custom vendor extension.  The main difference between a regular
+     array and the vector variant is that vectors are passed by value
+     to functions.  */
+  attr = dwarf_attr (die, DW_AT_GNU_vector);
+  if (attr)
+    TYPE_FLAGS (type) |= TYPE_FLAG_VECTOR;
+
+  do_cleanups (back_to);
+
+  /* Install the type in the die. */
+  die->type = type;
+}
+
+/* First cut: install each common block member as a global variable.  */
+
+static void
+read_common_block (struct die_info *die, struct objfile *objfile,
+                  const struct comp_unit_head *cu_header)
+{
+  struct die_info *child_die;
+  struct attribute *attr;
+  struct symbol *sym;
+  CORE_ADDR base = (CORE_ADDR) 0;
+
+  attr = dwarf_attr (die, DW_AT_location);
+  if (attr)
+    {
+      /* Support the .debug_loc offsets */
+      if (attr_form_is_block (attr))
+        {
+          base = decode_locdesc (DW_BLOCK (attr), objfile, cu_header);
+        }
+      else if (attr->form == DW_FORM_data4 || attr->form == DW_FORM_data8)
+        {
+          complain (&dwarf2_complex_location_expr);
+        }
+      else
+        {
+          complain (&dwarf2_invalid_attrib_class, "DW_AT_location",
+                    "common block member");
+        }
+    }
+  if (die->has_children)
+    {
+      child_die = die->next;
+      while (child_die && child_die->tag)
+       {
+         sym = new_symbol (child_die, NULL, objfile, cu_header);
+         attr = dwarf_attr (child_die, DW_AT_data_member_location);
+         if (attr)
+           {
+             SYMBOL_VALUE_ADDRESS (sym) =
+               base + decode_locdesc (DW_BLOCK (attr), objfile, cu_header);
+             add_symbol_to_list (sym, &global_symbols);
+           }
+         child_die = sibling_die (child_die);
+       }
+    }
+}
+
+/* Extract all information from a DW_TAG_pointer_type DIE and add to
+   the user defined type vector.  */
+
+static void
+read_tag_pointer_type (struct die_info *die, struct objfile *objfile,
+                      const struct comp_unit_head *cu_header)
+{
+  struct type *type;
+  struct attribute *attr;
+
+  if (die->type)
+    {
+      return;
+    }
+
+  type = lookup_pointer_type (die_type (die, objfile, cu_header));
+  attr = dwarf_attr (die, DW_AT_byte_size);
+  if (attr)
+    {
+      TYPE_LENGTH (type) = DW_UNSND (attr);
+    }
+  else
+    {
+      TYPE_LENGTH (type) = cu_header->addr_size;
+    }
+  die->type = type;
+}
+
+/* Extract all information from a DW_TAG_ptr_to_member_type DIE and add to
+   the user defined type vector.  */
+
+static void
+read_tag_ptr_to_member_type (struct die_info *die, struct objfile *objfile,
+                            const struct comp_unit_head *cu_header)
+{
+  struct type *type;
+  struct type *to_type;
+  struct type *domain;
+
+  if (die->type)
+    {
+      return;
+    }
+
+  type = alloc_type (objfile);
+  to_type = die_type (die, objfile, cu_header);
+  domain = die_containing_type (die, objfile, cu_header);
+  smash_to_member_type (type, domain, to_type);
+
+  die->type = type;
+}
+
+/* Extract all information from a DW_TAG_reference_type DIE and add to
+   the user defined type vector.  */
+
+static void
+read_tag_reference_type (struct die_info *die, struct objfile *objfile,
+                        const struct comp_unit_head *cu_header)
+{
+  struct type *type;
+  struct attribute *attr;
+
+  if (die->type)
+    {
+      return;
+    }
+
+  type = lookup_reference_type (die_type (die, objfile, cu_header));
+  attr = dwarf_attr (die, DW_AT_byte_size);
+  if (attr)
+    {
+      TYPE_LENGTH (type) = DW_UNSND (attr);
+    }
+  else
+    {
+      TYPE_LENGTH (type) = cu_header->addr_size;
+    }
+  die->type = type;
+}
+
+static void
+read_tag_const_type (struct die_info *die, struct objfile *objfile,
+                    const struct comp_unit_head *cu_header)
+{
+  struct type *base_type;
+
+  if (die->type)
+    {
+      return;
+    }
+
+  base_type = die_type (die, objfile, cu_header);
+  die->type = make_cv_type (1, TYPE_VOLATILE (base_type), base_type, 0);
+}
+
+static void
+read_tag_volatile_type (struct die_info *die, struct objfile *objfile,
+                       const struct comp_unit_head *cu_header)
+{
+  struct type *base_type;
+
+  if (die->type)
+    {
+      return;
+    }
+
+  base_type = die_type (die, objfile, cu_header);
+  die->type = make_cv_type (TYPE_CONST (base_type), 1, base_type, 0);
+}
+
+/* Extract all information from a DW_TAG_string_type DIE and add to
+   the user defined type vector.  It isn't really a user defined type,
+   but it behaves like one, with other DIE's using an AT_user_def_type
+   attribute to reference it.  */
+
+static void
+read_tag_string_type (struct die_info *die, struct objfile *objfile)
+{
+  struct type *type, *range_type, *index_type, *char_type;
+  struct attribute *attr;
+  unsigned int length;
+
+  if (die->type)
+    {
+      return;
+    }
+
+  attr = dwarf_attr (die, DW_AT_string_length);
+  if (attr)
+    {
+      length = DW_UNSND (attr);
+    }
+  else
+    {
+      /* check for the DW_AT_byte_size attribute */
+      attr = dwarf_attr (die, DW_AT_byte_size);
+      if (attr)
+        {
+          length = DW_UNSND (attr);
+        }
+      else
+        {
+          length = 1;
+        }
+    }
+  index_type = dwarf2_fundamental_type (objfile, FT_INTEGER);
+  range_type = create_range_type (NULL, index_type, 1, length);
+  if (cu_language == language_fortran)
+    {
+      /* Need to create a unique string type for bounds
+         information */
+      type = create_string_type (0, range_type);
+    }
+  else
+    {
+      char_type = dwarf2_fundamental_type (objfile, FT_CHAR);
+      type = create_string_type (char_type, range_type);
+    }
+  die->type = type;
+}
+
+/* Handle DIES due to C code like:
+
+   struct foo
+   {
+   int (*funcp)(int a, long l);
+   int b;
+   };
+
+   ('funcp' generates a DW_TAG_subroutine_type DIE)
+ */
+
+static void
+read_subroutine_type (struct die_info *die, struct objfile *objfile,
+                     const struct comp_unit_head *cu_header)
+{
+  struct type *type;           /* Type that this function returns */
+  struct type *ftype;          /* Function that returns above type */
+  struct attribute *attr;
+
+  /* Decode the type that this subroutine returns */
+  if (die->type)
+    {
+      return;
+    }
+  type = die_type (die, objfile, cu_header);
+  ftype = lookup_function_type (type);
+
+  /* All functions in C++ have prototypes.  */
+  attr = dwarf_attr (die, DW_AT_prototyped);
+  if ((attr && (DW_UNSND (attr) != 0))
+      || cu_language == language_cplus)
+    TYPE_FLAGS (ftype) |= TYPE_FLAG_PROTOTYPED;
+
+  if (die->has_children)
+    {
+      struct die_info *child_die;
+      int nparams = 0;
+      int iparams = 0;
+
+      /* Count the number of parameters.
+         FIXME: GDB currently ignores vararg functions, but knows about
+         vararg member functions.  */
+      child_die = die->next;
+      while (child_die && child_die->tag)
+       {
+         if (child_die->tag == DW_TAG_formal_parameter)
+           nparams++;
+         else if (child_die->tag == DW_TAG_unspecified_parameters)
+           TYPE_FLAGS (ftype) |= TYPE_FLAG_VARARGS;
+         child_die = sibling_die (child_die);
+       }
+
+      /* Allocate storage for parameters and fill them in.  */
+      TYPE_NFIELDS (ftype) = nparams;
+      TYPE_FIELDS (ftype) = (struct field *)
+       TYPE_ALLOC (ftype, nparams * sizeof (struct field));
+
+      child_die = die->next;
+      while (child_die && child_die->tag)
+       {
+         if (child_die->tag == DW_TAG_formal_parameter)
+           {
+             /* Dwarf2 has no clean way to discern C++ static and non-static
+                member functions. G++ helps GDB by marking the first
+                parameter for non-static member functions (which is the
+                this pointer) as artificial. We pass this information
+                to dwarf2_add_member_fn via TYPE_FIELD_ARTIFICIAL.  */
+             attr = dwarf_attr (child_die, DW_AT_artificial);
+             if (attr)
+               TYPE_FIELD_ARTIFICIAL (ftype, iparams) = DW_UNSND (attr);
+             else
+               TYPE_FIELD_ARTIFICIAL (ftype, iparams) = 0;
+             TYPE_FIELD_TYPE (ftype, iparams) = die_type (child_die, objfile,
+                                                          cu_header);
+             iparams++;
+           }
+         child_die = sibling_die (child_die);
+       }
+    }
+
+  die->type = ftype;
+}
+
+static void
+read_typedef (struct die_info *die, struct objfile *objfile,
+             const struct comp_unit_head *cu_header)
+{
+  struct attribute *attr;
+  char *name = NULL;
+
+  if (!die->type)
+    {
+      attr = dwarf_attr (die, DW_AT_name);
+      if (attr && DW_STRING (attr))
+       {
+         name = DW_STRING (attr);
+       }
+      die->type = init_type (TYPE_CODE_TYPEDEF, 0, TYPE_FLAG_TARGET_STUB, name, objfile);
+      TYPE_TARGET_TYPE (die->type) = die_type (die, objfile, cu_header);
+    }
+}
+
+/* Find a representation of a given base type and install
+   it in the TYPE field of the die.  */
+
+static void
+read_base_type (struct die_info *die, struct objfile *objfile)
+{
+  struct type *type;
+  struct attribute *attr;
+  int encoding = 0, size = 0;
+
+  /* If we've already decoded this die, this is a no-op. */
+  if (die->type)
+    {
+      return;
+    }
+
+  attr = dwarf_attr (die, DW_AT_encoding);
+  if (attr)
+    {
+      encoding = DW_UNSND (attr);
+    }
+  attr = dwarf_attr (die, DW_AT_byte_size);
+  if (attr)
+    {
+      size = DW_UNSND (attr);
+    }
+  attr = dwarf_attr (die, DW_AT_name);
+  if (attr && DW_STRING (attr))
+    {
+      enum type_code code = TYPE_CODE_INT;
+      int type_flags = 0;
+
+      switch (encoding)
+       {
+       case DW_ATE_address:
+         /* Turn DW_ATE_address into a void * pointer.  */
+         code = TYPE_CODE_PTR;
+         type_flags |= TYPE_FLAG_UNSIGNED;
+         break;
+       case DW_ATE_boolean:
+         code = TYPE_CODE_BOOL;
+         type_flags |= TYPE_FLAG_UNSIGNED;
+         break;
+       case DW_ATE_complex_float:
+         code = TYPE_CODE_COMPLEX;
+         break;
+       case DW_ATE_float:
+         code = TYPE_CODE_FLT;
+         break;
+       case DW_ATE_signed:
+       case DW_ATE_signed_char:
+         break;
+       case DW_ATE_unsigned:
+       case DW_ATE_unsigned_char:
+         type_flags |= TYPE_FLAG_UNSIGNED;
+         break;
+       default:
+         complain (&dwarf2_unsupported_at_encoding,
+                   dwarf_type_encoding_name (encoding));
+         break;
+       }
+      type = init_type (code, size, type_flags, DW_STRING (attr), objfile);
+      if (encoding == DW_ATE_address)
+       TYPE_TARGET_TYPE (type) = dwarf2_fundamental_type (objfile, FT_VOID);
+      else if (encoding == DW_ATE_complex_float)
+       {
+         if (size == 32)
+           TYPE_TARGET_TYPE (type)
+             = dwarf2_fundamental_type (objfile, FT_EXT_PREC_FLOAT);
+         else if (size == 16)
+           TYPE_TARGET_TYPE (type)
+             = dwarf2_fundamental_type (objfile, FT_DBL_PREC_FLOAT);
+         else if (size == 8)
+           TYPE_TARGET_TYPE (type)
+             = dwarf2_fundamental_type (objfile, FT_FLOAT);
+       }
+    }
+  else
+    {
+      type = dwarf_base_type (encoding, size, objfile);
+    }
+  die->type = type;
+}
+
+/* Read a whole compilation unit into a linked list of dies.  */
+
+static struct die_info *
+read_comp_unit (char *info_ptr, bfd *abfd,
+               const struct comp_unit_head *cu_header)
+{
+  struct die_info *first_die, *last_die, *die;
+  char *cur_ptr;
+  int nesting_level;
+
+  /* Reset die reference table; we are
+     building new ones now.  */
+  dwarf2_empty_hash_tables ();
+
+  cur_ptr = info_ptr;
+  nesting_level = 0;
+  first_die = last_die = NULL;
+  do
+    {
+      cur_ptr = read_full_die (&die, abfd, cur_ptr, cu_header);
+      if (die->has_children)
+       {
+         nesting_level++;
+       }
+      if (die->tag == 0)
+       {
+         nesting_level--;
+       }
+
+      die->next = NULL;
+
+      /* Enter die in reference hash table */
+      store_in_ref_table (die->offset, die);
+
+      if (!first_die)
+       {
+         first_die = last_die = die;
+       }
+      else
+       {
+         last_die->next = die;
+         last_die = die;
+       }
+    }
+  while (nesting_level > 0);
+  return first_die;
+}
+
+/* Free a linked list of dies.  */
+
+static void
+free_die_list (struct die_info *dies)
+{
+  struct die_info *die, *next;
+
+  die = dies;
+  while (die)
+    {
+      next = die->next;
+      xfree (die->attrs);
+      xfree (die);
+      die = next;
+    }
+}
+
+static void
+do_free_die_list_cleanup (void *dies)
+{
+  free_die_list (dies);
+}
+
+static struct cleanup *
+make_cleanup_free_die_list (struct die_info *dies)
+{
+  return make_cleanup (do_free_die_list_cleanup, dies);
+}
+
+
+/* Read the contents of the section at OFFSET and of size SIZE from the
+   object file specified by OBJFILE into the psymbol_obstack and return it.  */
+
+char *
+dwarf2_read_section (struct objfile *objfile, file_ptr offset,
+                    unsigned int size)
+{
+  bfd *abfd = objfile->obfd;
+  char *buf;
+
+  if (size == 0)
+    return NULL;
+
+  buf = (char *) obstack_alloc (&objfile->psymbol_obstack, size);
+  if ((bfd_seek (abfd, offset, SEEK_SET) != 0) ||
+      (bfd_bread (buf, size, abfd) != size))
+    {
+      buf = NULL;
+      error ("Dwarf Error: Can't read DWARF data from '%s'",
+            bfd_get_filename (abfd));
+    }
+  return buf;
+}
+
+/* In DWARF version 2, the description of the debugging information is
+   stored in a separate .debug_abbrev section.  Before we read any
+   dies from a section we read in all abbreviations and install them
+   in a hash table.  */
+
+static void
+dwarf2_read_abbrevs (bfd *abfd, unsigned int offset)
+{
+  char *abbrev_ptr;
+  struct abbrev_info *cur_abbrev;
+  unsigned int abbrev_number, bytes_read, abbrev_name;
+  unsigned int abbrev_form, hash_number;
+
+  /* empty the table */
+  dwarf2_empty_abbrev_table (NULL);
+
+  abbrev_ptr = dwarf_abbrev_buffer + offset;
+  abbrev_number = read_unsigned_leb128 (abfd, abbrev_ptr, &bytes_read);
+  abbrev_ptr += bytes_read;
+
+  /* loop until we reach an abbrev number of 0 */
+  while (abbrev_number)
+    {
+      cur_abbrev = dwarf_alloc_abbrev ();
+
+      /* read in abbrev header */
+      cur_abbrev->number = abbrev_number;
+      cur_abbrev->tag = read_unsigned_leb128 (abfd, abbrev_ptr, &bytes_read);
+      abbrev_ptr += bytes_read;
+      cur_abbrev->has_children = read_1_byte (abfd, abbrev_ptr);
+      abbrev_ptr += 1;
+
+      /* now read in declarations */
+      abbrev_name = read_unsigned_leb128 (abfd, abbrev_ptr, &bytes_read);
+      abbrev_ptr += bytes_read;
+      abbrev_form = read_unsigned_leb128 (abfd, abbrev_ptr, &bytes_read);
+      abbrev_ptr += bytes_read;
+      while (abbrev_name)
+       {
+         if ((cur_abbrev->num_attrs % ATTR_ALLOC_CHUNK) == 0)
+           {
+             cur_abbrev->attrs = (struct attr_abbrev *)
+               xrealloc (cur_abbrev->attrs,
+                         (cur_abbrev->num_attrs + ATTR_ALLOC_CHUNK)
+                         * sizeof (struct attr_abbrev));
+           }
+         cur_abbrev->attrs[cur_abbrev->num_attrs].name = abbrev_name;
+         cur_abbrev->attrs[cur_abbrev->num_attrs++].form = abbrev_form;
+         abbrev_name = read_unsigned_leb128 (abfd, abbrev_ptr, &bytes_read);
+         abbrev_ptr += bytes_read;
+         abbrev_form = read_unsigned_leb128 (abfd, abbrev_ptr, &bytes_read);
+         abbrev_ptr += bytes_read;
+       }
+
+      hash_number = abbrev_number % ABBREV_HASH_SIZE;
+      cur_abbrev->next = dwarf2_abbrevs[hash_number];
+      dwarf2_abbrevs[hash_number] = cur_abbrev;
+
+      /* Get next abbreviation.
+         Under Irix6 the abbreviations for a compilation unit are not
+         always properly terminated with an abbrev number of 0.
+         Exit loop if we encounter an abbreviation which we have
+         already read (which means we are about to read the abbreviations
+         for the next compile unit) or if the end of the abbreviation
+         table is reached.  */
+      if ((unsigned int) (abbrev_ptr - dwarf_abbrev_buffer)
+         >= dwarf_abbrev_size)
+       break;
+      abbrev_number = read_unsigned_leb128 (abfd, abbrev_ptr, &bytes_read);
+      abbrev_ptr += bytes_read;
+      if (dwarf2_lookup_abbrev (abbrev_number) != NULL)
+       break;
+    }
+}
+
+/* Empty the abbrev table for a new compilation unit.  */
+
+/* ARGSUSED */
+static void
+dwarf2_empty_abbrev_table (PTR ignore)
+{
+  int i;
+  struct abbrev_info *abbrev, *next;
+
+  for (i = 0; i < ABBREV_HASH_SIZE; ++i)
+    {
+      next = NULL;
+      abbrev = dwarf2_abbrevs[i];
+      while (abbrev)
+       {
+         next = abbrev->next;
+         xfree (abbrev->attrs);
+         xfree (abbrev);
+         abbrev = next;
+       }
+      dwarf2_abbrevs[i] = NULL;
+    }
+}
+
+/* Lookup an abbrev_info structure in the abbrev hash table.  */
+
+static struct abbrev_info *
+dwarf2_lookup_abbrev (unsigned int number)
+{
+  unsigned int hash_number;
+  struct abbrev_info *abbrev;
+
+  hash_number = number % ABBREV_HASH_SIZE;
+  abbrev = dwarf2_abbrevs[hash_number];
+
+  while (abbrev)
+    {
+      if (abbrev->number == number)
+       return abbrev;
+      else
+       abbrev = abbrev->next;
+    }
+  return NULL;
+}
+
+/* Read a minimal amount of information into the minimal die structure.  */
+
+static char *
+read_partial_die (struct partial_die_info *part_die, bfd *abfd,
+                 char *info_ptr, const struct comp_unit_head *cu_header)
+{
+  unsigned int abbrev_number, bytes_read, i;
+  struct abbrev_info *abbrev;
+  struct attribute attr;
+  struct attribute spec_attr;
+  int found_spec_attr = 0;
+  int has_low_pc_attr = 0;
+  int has_high_pc_attr = 0;
+
+  *part_die = zeroed_partial_die;
+  abbrev_number = read_unsigned_leb128 (abfd, info_ptr, &bytes_read);
+  info_ptr += bytes_read;
+  if (!abbrev_number)
+    return info_ptr;
+
+  abbrev = dwarf2_lookup_abbrev (abbrev_number);
+  if (!abbrev)
+    {
+      error ("Dwarf Error: Could not find abbrev number %d.", abbrev_number);
+    }
+  part_die->offset = info_ptr - dwarf_info_buffer;
+  part_die->tag = abbrev->tag;
+  part_die->has_children = abbrev->has_children;
+  part_die->abbrev = abbrev_number;
+
+  for (i = 0; i < abbrev->num_attrs; ++i)
+    {
+      info_ptr = read_attribute (&attr, &abbrev->attrs[i], abfd,
+                                info_ptr, cu_header);
+
+      /* Store the data if it is of an attribute we want to keep in a
+         partial symbol table.  */
+      switch (attr.name)
+       {
+       case DW_AT_name:
+
+         /* Prefer DW_AT_MIPS_linkage_name over DW_AT_name.  */
+         if (part_die->name == NULL)
+           part_die->name = DW_STRING (&attr);
+         break;
+       case DW_AT_MIPS_linkage_name:
+         part_die->name = DW_STRING (&attr);
+         break;
+       case DW_AT_low_pc:
+         has_low_pc_attr = 1;
+         part_die->lowpc = DW_ADDR (&attr);
+         break;
+       case DW_AT_high_pc:
+         has_high_pc_attr = 1;
+         part_die->highpc = DW_ADDR (&attr);
+         break;
+       case DW_AT_location:
+          /* Support the .debug_loc offsets */
+          if (attr_form_is_block (&attr))
+            {
+              part_die->locdesc = DW_BLOCK (&attr);
+            }
+          else if (attr.form == DW_FORM_data4 || attr.form == DW_FORM_data8)
+            {
+              complain (&dwarf2_complex_location_expr);
+            }
+          else
+            {
+              complain (&dwarf2_invalid_attrib_class, "DW_AT_location",
+                        "partial symbol information");
+            }
+         break;
+       case DW_AT_language:
+         part_die->language = DW_UNSND (&attr);
+         break;
+       case DW_AT_external:
+         part_die->is_external = DW_UNSND (&attr);
+         break;
+       case DW_AT_declaration:
+         part_die->is_declaration = DW_UNSND (&attr);
+         break;
+       case DW_AT_type:
+         part_die->has_type = 1;
+         break;
+       case DW_AT_abstract_origin:
+       case DW_AT_specification:
+         found_spec_attr = 1;
+         spec_attr = attr;
+         break;
+       case DW_AT_sibling:
+         /* Ignore absolute siblings, they might point outside of
+            the current compile unit.  */
+         if (attr.form == DW_FORM_ref_addr)
+           complain (&dwarf2_absolute_sibling_complaint);
+         else
+           part_die->sibling =
+             dwarf_info_buffer + dwarf2_get_ref_die_offset (&attr);
+         break;
+       default:
+         break;
+       }
+    }
+
+  /* If we found a reference attribute and the die has no name, try
+     to find a name in the referred to die.  */
+
+  if (found_spec_attr && part_die->name == NULL)
+    {
+      struct partial_die_info spec_die;
+      char *spec_ptr;
+      int dummy;
+
+      spec_ptr = dwarf_info_buffer + dwarf2_get_ref_die_offset (&spec_attr);
+      read_partial_die (&spec_die, abfd, spec_ptr, cu_header);
+      if (spec_die.name)
+       {
+         part_die->name = spec_die.name;
+
+         /* Copy DW_AT_external attribute if it is set.  */
+         if (spec_die.is_external)
+           part_die->is_external = spec_die.is_external;
+       }
+    }
+
+  /* When using the GNU linker, .gnu.linkonce. sections are used to
+     eliminate duplicate copies of functions and vtables and such.
+     The linker will arbitrarily choose one and discard the others.
+     The AT_*_pc values for such functions refer to local labels in
+     these sections.  If the section from that file was discarded, the
+     labels are not in the output, so the relocs get a value of 0.
+     If this is a discarded function, mark the pc bounds as invalid,
+     so that GDB will ignore it.  */
+  if (has_low_pc_attr && has_high_pc_attr
+      && part_die->lowpc < part_die->highpc
+      && (part_die->lowpc != 0
+         || (bfd_get_file_flags (abfd) & HAS_RELOC)))
+    part_die->has_pc_info = 1;
+  return info_ptr;
+}
+
+/* Read the die from the .debug_info section buffer.  And set diep to
+   point to a newly allocated die with its information.  */
+
+static char *
+read_full_die (struct die_info **diep, bfd *abfd, char *info_ptr,
+              const struct comp_unit_head *cu_header)
+{
+  unsigned int abbrev_number, bytes_read, i, offset;
+  struct abbrev_info *abbrev;
+  struct die_info *die;
+
+  offset = info_ptr - dwarf_info_buffer;
+  abbrev_number = read_unsigned_leb128 (abfd, info_ptr, &bytes_read);
+  info_ptr += bytes_read;
+  if (!abbrev_number)
+    {
+      die = dwarf_alloc_die ();
+      die->tag = 0;
+      die->abbrev = abbrev_number;
+      die->type = NULL;
+      *diep = die;
+      return info_ptr;
+    }
+
+  abbrev = dwarf2_lookup_abbrev (abbrev_number);
+  if (!abbrev)
+    {
+      error ("Dwarf Error: could not find abbrev number %d.", abbrev_number);
+    }
+  die = dwarf_alloc_die ();
+  die->offset = offset;
+  die->tag = abbrev->tag;
+  die->has_children = abbrev->has_children;
+  die->abbrev = abbrev_number;
+  die->type = NULL;
+
+  die->num_attrs = abbrev->num_attrs;
+  die->attrs = (struct attribute *)
+    xmalloc (die->num_attrs * sizeof (struct attribute));
+
+  for (i = 0; i < abbrev->num_attrs; ++i)
+    {
+      info_ptr = read_attribute (&die->attrs[i], &abbrev->attrs[i],
+                                abfd, info_ptr, cu_header);
+    }
+
+  *diep = die;
+  return info_ptr;
+}
+
+/* Read an attribute value described by an attribute form.  */
+
+static char *
+read_attribute_value (struct attribute *attr, unsigned form,
+               bfd *abfd, char *info_ptr,
+               const struct comp_unit_head *cu_header)
+{
+  unsigned int bytes_read;
+  struct dwarf_block *blk;
+
+  attr->form = form;
+  switch (form)
+    {
+    case DW_FORM_addr:
+    case DW_FORM_ref_addr:
+      DW_ADDR (attr) = read_address (abfd, info_ptr, cu_header, &bytes_read);
+      info_ptr += bytes_read;
+      break;
+    case DW_FORM_block2:
+      blk = dwarf_alloc_block ();
+      blk->size = read_2_bytes (abfd, info_ptr);
+      info_ptr += 2;
+      blk->data = read_n_bytes (abfd, info_ptr, blk->size);
+      info_ptr += blk->size;
+      DW_BLOCK (attr) = blk;
+      break;
+    case DW_FORM_block4:
+      blk = dwarf_alloc_block ();
+      blk->size = read_4_bytes (abfd, info_ptr);
+      info_ptr += 4;
+      blk->data = read_n_bytes (abfd, info_ptr, blk->size);
+      info_ptr += blk->size;
+      DW_BLOCK (attr) = blk;
+      break;
+    case DW_FORM_data2:
+      DW_UNSND (attr) = read_2_bytes (abfd, info_ptr);
+      info_ptr += 2;
+      break;
+    case DW_FORM_data4:
+      DW_UNSND (attr) = read_4_bytes (abfd, info_ptr);
+      info_ptr += 4;
+      break;
+    case DW_FORM_data8:
+      DW_UNSND (attr) = read_8_bytes (abfd, info_ptr);
+      info_ptr += 8;
+      break;
+    case DW_FORM_string:
+      DW_STRING (attr) = read_string (abfd, info_ptr, &bytes_read);
+      info_ptr += bytes_read;
+      break;
+    case DW_FORM_strp:
+      DW_STRING (attr) = read_indirect_string (abfd, info_ptr, cu_header,
+                                              &bytes_read);
+      info_ptr += bytes_read;
+      break;
+    case DW_FORM_block:
+      blk = dwarf_alloc_block ();
+      blk->size = read_unsigned_leb128 (abfd, info_ptr, &bytes_read);
+      info_ptr += bytes_read;
+      blk->data = read_n_bytes (abfd, info_ptr, blk->size);
+      info_ptr += blk->size;
+      DW_BLOCK (attr) = blk;
+      break;
+    case DW_FORM_block1:
+      blk = dwarf_alloc_block ();
+      blk->size = read_1_byte (abfd, info_ptr);
+      info_ptr += 1;
+      blk->data = read_n_bytes (abfd, info_ptr, blk->size);
+      info_ptr += blk->size;
+      DW_BLOCK (attr) = blk;
+      break;
+    case DW_FORM_data1:
+      DW_UNSND (attr) = read_1_byte (abfd, info_ptr);
+      info_ptr += 1;
+      break;
+    case DW_FORM_flag:
+      DW_UNSND (attr) = read_1_byte (abfd, info_ptr);
+      info_ptr += 1;
+      break;
+    case DW_FORM_sdata:
+      DW_SND (attr) = read_signed_leb128 (abfd, info_ptr, &bytes_read);
+      info_ptr += bytes_read;
+      break;
+    case DW_FORM_udata:
+      DW_UNSND (attr) = read_unsigned_leb128 (abfd, info_ptr, &bytes_read);
+      info_ptr += bytes_read;
+      break;
+    case DW_FORM_ref1:
+      DW_UNSND (attr) = read_1_byte (abfd, info_ptr);
+      info_ptr += 1;
+      break;
+    case DW_FORM_ref2:
+      DW_UNSND (attr) = read_2_bytes (abfd, info_ptr);
+      info_ptr += 2;
+      break;
+    case DW_FORM_ref4:
+      DW_UNSND (attr) = read_4_bytes (abfd, info_ptr);
+      info_ptr += 4;
+      break;
+    case DW_FORM_ref8:
+      DW_UNSND (attr) = read_8_bytes (abfd, info_ptr);
+      info_ptr += 8;
+      break;
+    case DW_FORM_ref_udata:
+      DW_UNSND (attr) = read_unsigned_leb128 (abfd, info_ptr, &bytes_read);
+      info_ptr += bytes_read;
+      break;
+    case DW_FORM_indirect:
+      form = read_unsigned_leb128 (abfd, info_ptr, &bytes_read);
+      info_ptr += bytes_read;
+      info_ptr = read_attribute_value (attr, form, abfd, info_ptr, cu_header);
+      break;
+    default:
+      error ("Dwarf Error: Cannot handle %s in DWARF reader.",
+            dwarf_form_name (form));
+    }
+  return info_ptr;
+}
+
+/* Read an attribute described by an abbreviated attribute.  */
+
+static char *
+read_attribute (struct attribute *attr, struct attr_abbrev *abbrev,
+               bfd *abfd, char *info_ptr,
+               const struct comp_unit_head *cu_header)
+{
+  attr->name = abbrev->name;
+  return read_attribute_value (attr, abbrev->form, abfd, info_ptr, cu_header);
+}
+
+/* read dwarf information from a buffer */
+
+static unsigned int
+read_1_byte (bfd *abfd, char *buf)
+{
+  return bfd_get_8 (abfd, (bfd_byte *) buf);
+}
+
+static int
+read_1_signed_byte (bfd *abfd, char *buf)
+{
+  return bfd_get_signed_8 (abfd, (bfd_byte *) buf);
+}
+
+static unsigned int
+read_2_bytes (bfd *abfd, char *buf)
+{
+  return bfd_get_16 (abfd, (bfd_byte *) buf);
+}
+
+static int
+read_2_signed_bytes (bfd *abfd, char *buf)
+{
+  return bfd_get_signed_16 (abfd, (bfd_byte *) buf);
+}
+
+static unsigned int
+read_4_bytes (bfd *abfd, char *buf)
+{
+  return bfd_get_32 (abfd, (bfd_byte *) buf);
+}
+
+static int
+read_4_signed_bytes (bfd *abfd, char *buf)
+{
+  return bfd_get_signed_32 (abfd, (bfd_byte *) buf);
+}
+
+static unsigned long
+read_8_bytes (bfd *abfd, char *buf)
+{
+  return bfd_get_64 (abfd, (bfd_byte *) buf);
+}
+
+static CORE_ADDR
+read_address (bfd *abfd, char *buf, const struct comp_unit_head *cu_header,
+             int *bytes_read)
+{
+  CORE_ADDR retval = 0;
+
+  if (cu_header->signed_addr_p)
+    {
+      switch (cu_header->addr_size)
+       {
+       case 2:
+         retval = bfd_get_signed_16 (abfd, (bfd_byte *) buf);
+         break;
+       case 4:
+         retval = bfd_get_signed_32 (abfd, (bfd_byte *) buf);
+         break;
+       case 8:
+         retval = bfd_get_signed_64 (abfd, (bfd_byte *) buf);
+         break;
+       default:
+         internal_error (__FILE__, __LINE__,
+                         "read_address: bad switch, signed");
+       }
+    }
+  else
+    {
+      switch (cu_header->addr_size)
+       {
+       case 2:
+         retval = bfd_get_16 (abfd, (bfd_byte *) buf);
+         break;
+       case 4:
+         retval = bfd_get_32 (abfd, (bfd_byte *) buf);
+         break;
+       case 8:
+         retval = bfd_get_64 (abfd, (bfd_byte *) buf);
+         break;
+       default:
+         internal_error (__FILE__, __LINE__,
+                         "read_address: bad switch, unsigned");
+       }
+    }
+
+  *bytes_read = cu_header->addr_size;
+  return retval;
+}
+
+/* Read the initial length from a section.  The (draft) DWARF 3
+   specification allows the initial length to take up either 4 bytes
+   or 12 bytes.  If the first 4 bytes are 0xffffffff, then the next 8
+   bytes describe the length and all offsets will be 8 bytes in length
+   instead of 4.
+
+   An older, non-standard 64-bit format is also handled by this
+   function.  The older format in question stores the initial length
+   as an 8-byte quantity without an escape value.  Lengths greater
+   than 2^32 aren't very common which means that the initial 4 bytes
+   is almost always zero.  Since a length value of zero doesn't make
+   sense for the 32-bit format, this initial zero can be considered to
+   be an escape value which indicates the presence of the older 64-bit
+   format.  As written, the code can't detect (old format) lengths
+   greater than 4GB.  If it becomes necessary to handle lengths somewhat
+   larger than 4GB, we could allow other small values (such as the
+   non-sensical values of 1, 2, and 3) to also be used as escape values
+   indicating the presence of the old format.
+
+   The value returned via bytes_read should be used to increment
+   the relevant pointer after calling read_initial_length().
+   
+   As a side effect, this function sets the fields initial_length_size
+   and offset_size in cu_header to the values appropriate for the
+   length field.  (The format of the initial length field determines
+   the width of file offsets to be fetched later with fetch_offset().)
+   
+   [ Note:  read_initial_length() and read_offset() are based on the
+     document entitled "DWARF Debugging Information Format", revision
+     3, draft 8, dated November 19, 2001.  This document was obtained
+     from:
+
+       http://reality.sgiweb.org/davea/dwarf3-draft8-011125.pdf
+     
+     This document is only a draft and is subject to change.  (So beware.)
+
+     Details regarding the older, non-standard 64-bit format were
+     determined empirically by examining 64-bit ELF files produced
+     by the SGI toolchain on an IRIX 6.5 machine.
+
+     - Kevin, July 16, 2002
+   ] */
+
+static LONGEST
+read_initial_length (bfd *abfd, char *buf, struct comp_unit_head *cu_header,
+                     int *bytes_read)
+{
+  LONGEST retval = 0;
+
+  retval = bfd_get_32 (abfd, (bfd_byte *) buf);
+
+  if (retval == 0xffffffff)
+    {
+      retval = bfd_get_64 (abfd, (bfd_byte *) buf + 4);
+      *bytes_read = 12;
+      if (cu_header != NULL)
+       {
+         cu_header->initial_length_size = 12;
+         cu_header->offset_size = 8;
+       }
+    }
+  else if (retval == 0)
+    {
+      /* Handle (non-standard) 64-bit DWARF2 formats such as that used
+         by IRIX.  */
+      retval = bfd_get_64 (abfd, (bfd_byte *) buf);
+      *bytes_read = 8;
+      if (cu_header != NULL)
+       {
+         cu_header->initial_length_size = 8;
+         cu_header->offset_size = 8;
+       }
+    }
+  else
+    {
+      *bytes_read = 4;
+      if (cu_header != NULL)
+       {
+         cu_header->initial_length_size = 4;
+         cu_header->offset_size = 4;
+       }
+    }
+
+ return retval;
+}
+
+/* Read an offset from the data stream.  The size of the offset is
+   given by cu_header->offset_size. */
+
+static LONGEST
+read_offset (bfd *abfd, char *buf, const struct comp_unit_head *cu_header,
+             int *bytes_read)
+{
+  LONGEST retval = 0;
+
+  switch (cu_header->offset_size)
+    {
+    case 4:
+      retval = bfd_get_32 (abfd, (bfd_byte *) buf);
+      *bytes_read = 4;
+      break;
+    case 8:
+      retval = bfd_get_64 (abfd, (bfd_byte *) buf);
+      *bytes_read = 8;
+      break;
+    default:
+      internal_error (__FILE__, __LINE__,
+                     "read_offset: bad switch");
+    }
+
+ return retval;
+}
+
+static char *
+read_n_bytes (bfd *abfd, char *buf, unsigned int size)
+{
+  /* If the size of a host char is 8 bits, we can return a pointer
+     to the buffer, otherwise we have to copy the data to a buffer
+     allocated on the temporary obstack.  */
+  gdb_assert (HOST_CHAR_BIT == 8);
+  return buf;
+}
+
+static char *
+read_string (bfd *abfd, char *buf, unsigned int *bytes_read_ptr)
+{
+  /* If the size of a host char is 8 bits, we can return a pointer
+     to the string, otherwise we have to copy the string to a buffer
+     allocated on the temporary obstack.  */
+  gdb_assert (HOST_CHAR_BIT == 8);
+  if (*buf == '\0')
+    {
+      *bytes_read_ptr = 1;
+      return NULL;
+    }
+  *bytes_read_ptr = strlen (buf) + 1;
+  return buf;
+}
+
+static char *
+read_indirect_string (bfd *abfd, char *buf,
+                     const struct comp_unit_head *cu_header,
+                     unsigned int *bytes_read_ptr)
+{
+  LONGEST str_offset = read_offset (abfd, buf, cu_header,
+                                   (int *) bytes_read_ptr);
+
+  if (dwarf_str_buffer == NULL)
+    {
+      error ("DW_FORM_strp used without .debug_str section");
+      return NULL;
+    }
+  if (str_offset >= dwarf_str_size)
+    {
+      error ("DW_FORM_strp pointing outside of .debug_str section");
+      return NULL;
+    }
+  gdb_assert (HOST_CHAR_BIT == 8);
+  if (dwarf_str_buffer[str_offset] == '\0')
+    return NULL;
+  return dwarf_str_buffer + str_offset;
+}
+
+static unsigned long
+read_unsigned_leb128 (bfd *abfd, char *buf, unsigned int *bytes_read_ptr)
+{
+  unsigned long result;
+  unsigned int num_read;
+  int i, shift;
+  unsigned char byte;
+
+  result = 0;
+  shift = 0;
+  num_read = 0;
+  i = 0;
+  while (1)
+    {
+      byte = bfd_get_8 (abfd, (bfd_byte *) buf);
+      buf++;
+      num_read++;
+      result |= ((unsigned long)(byte & 127) << shift);
+      if ((byte & 128) == 0)
+       {
+         break;
+       }
+      shift += 7;
+    }
+  *bytes_read_ptr = num_read;
+  return result;
+}
+
+static long
+read_signed_leb128 (bfd *abfd, char *buf, unsigned int *bytes_read_ptr)
+{
+  long result;
+  int i, shift, size, num_read;
+  unsigned char byte;
+
+  result = 0;
+  shift = 0;
+  size = 32;
+  num_read = 0;
+  i = 0;
+  while (1)
+    {
+      byte = bfd_get_8 (abfd, (bfd_byte *) buf);
+      buf++;
+      num_read++;
+      result |= ((long)(byte & 127) << shift);
+      shift += 7;
+      if ((byte & 128) == 0)
+       {
+         break;
+       }
+    }
+  if ((shift < size) && (byte & 0x40))
+    {
+      result |= -(1 << shift);
+    }
+  *bytes_read_ptr = num_read;
+  return result;
+}
+
+static void
+set_cu_language (unsigned int lang)
+{
+  switch (lang)
+    {
+    case DW_LANG_C89:
+    case DW_LANG_C:
+      cu_language = language_c;
+      break;
+    case DW_LANG_C_plus_plus:
+      cu_language = language_cplus;
+      break;
+    case DW_LANG_Fortran77:
+    case DW_LANG_Fortran90:
+    case DW_LANG_Fortran95:
+      cu_language = language_fortran;
+      break;
+    case DW_LANG_Mips_Assembler:
+      cu_language = language_asm;
+      break;
+    case DW_LANG_Java:
+      cu_language = language_java;
+      break;
+    case DW_LANG_Ada83:
+    case DW_LANG_Ada95:
+    case DW_LANG_Cobol74:
+    case DW_LANG_Cobol85:
+    case DW_LANG_Pascal83:
+    case DW_LANG_Modula2:
+    default:
+      cu_language = language_unknown;
+      break;
+    }
+  cu_language_defn = language_def (cu_language);
+}
+
+/* Return the named attribute or NULL if not there.  */
+
+static struct attribute *
+dwarf_attr (struct die_info *die, unsigned int name)
+{
+  unsigned int i;
+  struct attribute *spec = NULL;
+
+  for (i = 0; i < die->num_attrs; ++i)
+    {
+      if (die->attrs[i].name == name)
+       {
+         return &die->attrs[i];
+       }
+      if (die->attrs[i].name == DW_AT_specification
+         || die->attrs[i].name == DW_AT_abstract_origin)
+       spec = &die->attrs[i];
+    }
+  if (spec)
+    {
+      struct die_info *ref_die =
+      follow_die_ref (dwarf2_get_ref_die_offset (spec));
+
+      if (ref_die)
+       return dwarf_attr (ref_die, name);
+    }
+
+  return NULL;
+}
+
+static int
+die_is_declaration (struct die_info *die)
+{
+  return (dwarf_attr (die, DW_AT_declaration)
+         && ! dwarf_attr (die, DW_AT_specification));
+}
+
+
+/* Free the line_header structure *LH, and any arrays and strings it
+   refers to.  */
+static void
+free_line_header (struct line_header *lh)
+{
+  if (lh->standard_opcode_lengths)
+    xfree (lh->standard_opcode_lengths);
+
+  /* Remember that all the lh->file_names[i].name pointers are
+     pointers into debug_line_buffer, and don't need to be freed.  */
+  if (lh->file_names)
+    xfree (lh->file_names);
+
+  /* Similarly for the include directory names.  */
+  if (lh->include_dirs)
+    xfree (lh->include_dirs);
+
+  xfree (lh);
+}
+
+
+/* Add an entry to LH's include directory table.  */
+static void
+add_include_dir (struct line_header *lh, char *include_dir)
+{
+  /* Grow the array if necessary.  */
+  if (lh->include_dirs_size == 0)
+    {
+      lh->include_dirs_size = 1; /* for testing */
+      lh->include_dirs = xmalloc (lh->include_dirs_size
+                                  * sizeof (*lh->include_dirs));
+    }
+  else if (lh->num_include_dirs >= lh->include_dirs_size)
+    {
+      lh->include_dirs_size *= 2;
+      lh->include_dirs = xrealloc (lh->include_dirs,
+                                   (lh->include_dirs_size
+                                    * sizeof (*lh->include_dirs)));
+    }
+
+  lh->include_dirs[lh->num_include_dirs++] = include_dir;
+}
+
+/* Add an entry to LH's file name table.  */
+static void
+add_file_name (struct line_header *lh,
+               char *name,
+               unsigned int dir_index,
+               unsigned int mod_time,
+               unsigned int length)
+{
+  struct file_entry *fe;
+
+  /* Grow the array if necessary.  */
+  if (lh->file_names_size == 0)
+    {
+      lh->file_names_size = 1; /* for testing */
+      lh->file_names = xmalloc (lh->file_names_size
+                                * sizeof (*lh->file_names));
+    }
+  else if (lh->num_file_names >= lh->file_names_size)
+    {
+      lh->file_names_size *= 2;
+      lh->file_names = xrealloc (lh->file_names,
+                                 (lh->file_names_size
+                                  * sizeof (*lh->file_names)));
+    }
+
+  fe = &lh->file_names[lh->num_file_names++];
+  fe->name = name;
+  fe->dir_index = dir_index;
+  fe->mod_time = mod_time;
+  fe->length = length;
+}
+
+/* Read the statement program header starting at OFFSET in
+   dwarf_line_buffer, according to the endianness of ABFD.  Return a
+   pointer to a struct line_header, allocated using xmalloc.
+
+   NOTE: the strings in the include directory and file name tables of
+   the returned object point into debug_line_buffer, and must not be
+   freed.  */
+static struct line_header *
+dwarf_decode_line_header (unsigned int offset, bfd *abfd,
+                          const struct comp_unit_head *cu_header)
+{
+  struct cleanup *back_to;
+  struct line_header *lh;
+  char *line_ptr;
+  int bytes_read;
+  int i;
+  char *cur_dir, *cur_file;
+
+  if (dwarf_line_buffer == NULL)
+    {
+      complain (&dwarf2_missing_line_number_section);
+      return 0;
+    }
+
+  /* Make sure that at least there's room for the total_length field.  That
+     could be 12 bytes long, but we're just going to fudge that.  */
+  if (offset + 4 >= dwarf_line_size)
+    {
+      complain (&dwarf2_statement_list_fits_in_line_number_section);
+      return 0;
+    }
+
+  lh = xmalloc (sizeof (*lh));
+  memset (lh, 0, sizeof (*lh));
+  back_to = make_cleanup ((make_cleanup_ftype *) free_line_header,
+                          (void *) lh);
+
+  line_ptr = dwarf_line_buffer + offset;
+
+  /* read in the header */
+  lh->total_length = read_initial_length (abfd, line_ptr, NULL, &bytes_read);
+  line_ptr += bytes_read;
+  if (line_ptr + lh->total_length > dwarf_line_buffer + dwarf_line_size)
+    {
+      complain (&dwarf2_statement_list_fits_in_line_number_section);
+      return 0;
+    }
+  lh->statement_program_end = line_ptr + lh->total_length;
+  lh->version = read_2_bytes (abfd, line_ptr);
+  line_ptr += 2;
+  lh->header_length = read_offset (abfd, line_ptr, cu_header, &bytes_read);
+  line_ptr += bytes_read;
+  lh->minimum_instruction_length = read_1_byte (abfd, line_ptr);
+  line_ptr += 1;
+  lh->default_is_stmt = read_1_byte (abfd, line_ptr);
+  line_ptr += 1;
+  lh->line_base = read_1_signed_byte (abfd, line_ptr);
+  line_ptr += 1;
+  lh->line_range = read_1_byte (abfd, line_ptr);
+  line_ptr += 1;
+  lh->opcode_base = read_1_byte (abfd, line_ptr);
+  line_ptr += 1;
+  lh->standard_opcode_lengths
+    = (unsigned char *) xmalloc (lh->opcode_base * sizeof (unsigned char));
+
+  lh->standard_opcode_lengths[0] = 1;  /* This should never be used anyway.  */
+  for (i = 1; i < lh->opcode_base; ++i)
+    {
+      lh->standard_opcode_lengths[i] = read_1_byte (abfd, line_ptr);
+      line_ptr += 1;
+    }
+
+  /* Read directory table  */
+  while ((cur_dir = read_string (abfd, line_ptr, &bytes_read)) != NULL)
+    {
+      line_ptr += bytes_read;
+      add_include_dir (lh, cur_dir);
+    }
+  line_ptr += bytes_read;
+
+  /* Read file name table */
+  while ((cur_file = read_string (abfd, line_ptr, &bytes_read)) != NULL)
+    {
+      unsigned int dir_index, mod_time, length;
+
+      line_ptr += bytes_read;
+      dir_index = read_unsigned_leb128 (abfd, line_ptr, &bytes_read);
+      line_ptr += bytes_read;
+      mod_time = read_unsigned_leb128 (abfd, line_ptr, &bytes_read);
+      line_ptr += bytes_read;
+      length = read_unsigned_leb128 (abfd, line_ptr, &bytes_read);
+      line_ptr += bytes_read;
+
+      add_file_name (lh, cur_file, dir_index, mod_time, length);
+    }
+  line_ptr += bytes_read;
+  lh->statement_program_start = line_ptr; 
+
+  if (line_ptr > dwarf_line_buffer + dwarf_line_size)
+    complain (&dwarf2_line_header_too_long);
+
+  discard_cleanups (back_to);
+  return lh;
+}
+
+/* This function exists to work around a bug in certain compilers
+   (particularly GCC 2.95), in which the first line number marker of a
+   function does not show up until after the prologue, right before
+   the second line number marker.  This function shifts ADDRESS down
+   to the beginning of the function if necessary, and is called on
+   addresses passed to record_line.  */
+
+static CORE_ADDR
+check_cu_functions (CORE_ADDR address)
+{
+  struct function_range *fn;
+
+  /* Find the function_range containing address.  */
+  if (!cu_first_fn)
+    return address;
+
+  if (!cu_cached_fn)
+    cu_cached_fn = cu_first_fn;
+
+  fn = cu_cached_fn;
+  while (fn)
+    if (fn->lowpc <= address && fn->highpc > address)
+      goto found;
+    else
+      fn = fn->next;
+
+  fn = cu_first_fn;
+  while (fn && fn != cu_cached_fn)
+    if (fn->lowpc <= address && fn->highpc > address)
+      goto found;
+    else
+      fn = fn->next;
+
+  return address;
+
+ found:
+  if (fn->seen_line)
+    return address;
+  if (address != fn->lowpc)
+    complain (&dwarf2_misplaced_line_number,
+             (unsigned long) address, fn->name);
+  fn->seen_line = 1;
+  return fn->lowpc;
+}
+
+/* Decode the line number information for the compilation unit whose
+   line number info is at OFFSET in the .debug_line section.
+   The compilation directory of the file is passed in COMP_DIR.  */
+
+static void
+dwarf_decode_lines (struct line_header *lh, char *comp_dir, bfd *abfd,
+                   const struct comp_unit_head *cu_header)
+{
+  char *line_ptr;
+  char *line_end;
+  unsigned int i, bytes_read;
+  char *cur_dir;
+  unsigned char op_code, extended_op, adj_opcode;
+
+  line_ptr = lh->statement_program_start;
+  line_end = lh->statement_program_end;
+
+  /* Read the statement sequences until there's nothing left.  */
+  while (line_ptr < line_end)
+    {
+      /* state machine registers  */
+      CORE_ADDR address = 0;
+      unsigned int file = 1;
+      unsigned int line = 1;
+      unsigned int column = 0;
+      int is_stmt = lh->default_is_stmt;
+      int basic_block = 0;
+      int end_sequence = 0;
+
+      /* Start a subfile for the current file of the state machine.  */
+      if (lh->num_file_names >= file)
+       {
+         /* lh->include_dirs and lh->file_names are 0-based, but the
+            directory and file name numbers in the statement program
+            are 1-based.  */
+          struct file_entry *fe = &lh->file_names[file - 1];
+          char *dir;
+          if (fe->dir_index)
+            dir = lh->include_dirs[fe->dir_index - 1];
+          else
+            dir = comp_dir;
+         dwarf2_start_subfile (fe->name, dir);
+       }
+
+      /* Decode the table. */
+      while (!end_sequence)
+       {
+         op_code = read_1_byte (abfd, line_ptr);
+         line_ptr += 1;
+
+         if (op_code >= lh->opcode_base)
+           {           /* Special operand.  */
+             adj_opcode = op_code - lh->opcode_base;
+             address += (adj_opcode / lh->line_range)
+               * lh->minimum_instruction_length;
+             line += lh->line_base + (adj_opcode % lh->line_range);
+             /* append row to matrix using current values */
+             address = check_cu_functions (address);
+             record_line (current_subfile, line, address);
+             basic_block = 1;
+           }
+         else switch (op_code)
+           {
+           case DW_LNS_extended_op:
+             line_ptr += 1;    /* ignore length */
+             extended_op = read_1_byte (abfd, line_ptr);
+             line_ptr += 1;
+             switch (extended_op)
+               {
+               case DW_LNE_end_sequence:
+                 end_sequence = 1;
+                 record_line (current_subfile, 0, address);
+                 break;
+               case DW_LNE_set_address:
+                 address = read_address (abfd, line_ptr, cu_header, &bytes_read);
+                 line_ptr += bytes_read;
+                 address += baseaddr;
+                 break;
+               case DW_LNE_define_file:
+                  {
+                    char *cur_file;
+                    unsigned int dir_index, mod_time, length;
+                    
+                    cur_file = read_string (abfd, line_ptr, &bytes_read);
+                    line_ptr += bytes_read;
+                    dir_index =
+                      read_unsigned_leb128 (abfd, line_ptr, &bytes_read);
+                    line_ptr += bytes_read;
+                    mod_time =
+                      read_unsigned_leb128 (abfd, line_ptr, &bytes_read);
+                    line_ptr += bytes_read;
+                    length =
+                      read_unsigned_leb128 (abfd, line_ptr, &bytes_read);
+                    line_ptr += bytes_read;
+                    add_file_name (lh, cur_file, dir_index, mod_time, length);
+                  }
+                 break;
+               default:
+                 complain (&dwarf2_mangled_line_number_section);
+                 return;
+               }
+             break;
+           case DW_LNS_copy:
+             address = check_cu_functions (address);
+             record_line (current_subfile, line, address);
+             basic_block = 0;
+             break;
+           case DW_LNS_advance_pc:
+             address += lh->minimum_instruction_length
+               * read_unsigned_leb128 (abfd, line_ptr, &bytes_read);
+             line_ptr += bytes_read;
+             break;
+           case DW_LNS_advance_line:
+             line += read_signed_leb128 (abfd, line_ptr, &bytes_read);
+             line_ptr += bytes_read;
+             break;
+           case DW_LNS_set_file:
+              {
+                /* lh->include_dirs and lh->file_names are 0-based,
+                   but the directory and file name numbers in the
+                   statement program are 1-based.  */
+                struct file_entry *fe;
+                char *dir;
+                file = read_unsigned_leb128 (abfd, line_ptr, &bytes_read);
+                line_ptr += bytes_read;
+                fe = &lh->file_names[file - 1];
+                if (fe->dir_index)
+                  dir = lh->include_dirs[fe->dir_index - 1];
+                else
+                  dir = comp_dir;
+                dwarf2_start_subfile (fe->name, dir);
+              }
+             break;
+           case DW_LNS_set_column:
+             column = read_unsigned_leb128 (abfd, line_ptr, &bytes_read);
+             line_ptr += bytes_read;
+             break;
+           case DW_LNS_negate_stmt:
+             is_stmt = (!is_stmt);
+             break;
+           case DW_LNS_set_basic_block:
+             basic_block = 1;
+             break;
+           /* Add to the address register of the state machine the
+              address increment value corresponding to special opcode
+              255.  Ie, this value is scaled by the minimum instruction
+              length since special opcode 255 would have scaled the
+              the increment.  */
+           case DW_LNS_const_add_pc:
+             address += (lh->minimum_instruction_length
+                         * ((255 - lh->opcode_base) / lh->line_range));
+             break;
+           case DW_LNS_fixed_advance_pc:
+             address += read_2_bytes (abfd, line_ptr);
+             line_ptr += 2;
+             break;
+           default:
+             {  /* Unknown standard opcode, ignore it.  */
+               int i;
+               for (i = 0; i < lh->standard_opcode_lengths[op_code]; i++)
+                 {
+                   (void) read_unsigned_leb128 (abfd, line_ptr, &bytes_read);
+                   line_ptr += bytes_read;
+                 }
+             }
+           }
+       }
+    }
+}
+
+/* Start a subfile for DWARF.  FILENAME is the name of the file and
+   DIRNAME the name of the source directory which contains FILENAME
+   or NULL if not known.
+   This routine tries to keep line numbers from identical absolute and
+   relative file names in a common subfile.
+
+   Using the `list' example from the GDB testsuite, which resides in
+   /srcdir and compiling it with Irix6.2 cc in /compdir using a filename
+   of /srcdir/list0.c yields the following debugging information for list0.c:
+
+   DW_AT_name:          /srcdir/list0.c
+   DW_AT_comp_dir:              /compdir
+   files.files[0].name: list0.h
+   files.files[0].dir:  /srcdir
+   files.files[1].name: list0.c
+   files.files[1].dir:  /srcdir
+
+   The line number information for list0.c has to end up in a single
+   subfile, so that `break /srcdir/list0.c:1' works as expected.  */
+
+static void
+dwarf2_start_subfile (char *filename, char *dirname)
+{
+  /* If the filename isn't absolute, try to match an existing subfile
+     with the full pathname.  */
+
+  if (!IS_ABSOLUTE_PATH (filename) && dirname != NULL)
+    {
+      struct subfile *subfile;
+      char *fullname = concat (dirname, "/", filename, NULL);
+
+      for (subfile = subfiles; subfile; subfile = subfile->next)
+       {
+         if (FILENAME_CMP (subfile->name, fullname) == 0)
+           {
+             current_subfile = subfile;
+             xfree (fullname);
+             return;
+           }
+       }
+      xfree (fullname);
+    }
+  start_subfile (filename, dirname);
+}
+
+/* Given a pointer to a DWARF information entry, figure out if we need
+   to make a symbol table entry for it, and if so, create a new entry
+   and return a pointer to it.
+   If TYPE is NULL, determine symbol type from the die, otherwise
+   used the passed type.  */
+
+static struct symbol *
+new_symbol (struct die_info *die, struct type *type, struct objfile *objfile,
+           const struct comp_unit_head *cu_header)
+{
+  struct symbol *sym = NULL;
+  char *name;
+  struct attribute *attr = NULL;
+  struct attribute *attr2 = NULL;
+  CORE_ADDR addr = 0;
+
+  name = dwarf2_linkage_name (die);
+  if (name)
+    {
+      sym = (struct symbol *) obstack_alloc (&objfile->symbol_obstack,
+                                            sizeof (struct symbol));
+      OBJSTAT (objfile, n_syms++);
+      memset (sym, 0, sizeof (struct symbol));
+      SYMBOL_NAME (sym) = obsavestring (name, strlen (name),
+                                       &objfile->symbol_obstack);
+
+      /* Default assumptions.
+         Use the passed type or decode it from the die.  */
+      SYMBOL_NAMESPACE (sym) = VAR_NAMESPACE;
+      SYMBOL_CLASS (sym) = LOC_STATIC;
+      if (type != NULL)
+       SYMBOL_TYPE (sym) = type;
+      else
+       SYMBOL_TYPE (sym) = die_type (die, objfile, cu_header);
+      attr = dwarf_attr (die, DW_AT_decl_line);
+      if (attr)
+       {
+         SYMBOL_LINE (sym) = DW_UNSND (attr);
+       }
+
+      /* If this symbol is from a C++ compilation, then attempt to
+         cache the demangled form for future reference.  This is a
+         typical time versus space tradeoff, that was decided in favor
+         of time because it sped up C++ symbol lookups by a factor of
+         about 20. */
+
+      SYMBOL_LANGUAGE (sym) = cu_language;
+      SYMBOL_INIT_DEMANGLED_NAME (sym, &objfile->symbol_obstack);
+      switch (die->tag)
+       {
+       case DW_TAG_label:
+         attr = dwarf_attr (die, DW_AT_low_pc);
+         if (attr)
+           {
+             SYMBOL_VALUE_ADDRESS (sym) = DW_ADDR (attr) + baseaddr;
+           }
+         SYMBOL_CLASS (sym) = LOC_LABEL;
+         break;
+       case DW_TAG_subprogram:
+         /* SYMBOL_BLOCK_VALUE (sym) will be filled in later by
+            finish_block.  */
+         SYMBOL_CLASS (sym) = LOC_BLOCK;
+         attr2 = dwarf_attr (die, DW_AT_external);
+         if (attr2 && (DW_UNSND (attr2) != 0))
+           {
+             add_symbol_to_list (sym, &global_symbols);
+           }
+         else
+           {
+             add_symbol_to_list (sym, list_in_scope);
+           }
+         break;
+       case DW_TAG_variable:
+         /* Compilation with minimal debug info may result in variables
+            with missing type entries. Change the misleading `void' type
+            to something sensible.  */
+         if (TYPE_CODE (SYMBOL_TYPE (sym)) == TYPE_CODE_VOID)
+           SYMBOL_TYPE (sym) = init_type (TYPE_CODE_INT,
+                                          TARGET_INT_BIT / HOST_CHAR_BIT, 0,
+                                          "<variable, no debug info>",
+                                          objfile);
+         attr = dwarf_attr (die, DW_AT_const_value);
+         if (attr)
+           {
+             dwarf2_const_value (attr, sym, objfile, cu_header);
+             attr2 = dwarf_attr (die, DW_AT_external);
+             if (attr2 && (DW_UNSND (attr2) != 0))
+               add_symbol_to_list (sym, &global_symbols);
+             else
+               add_symbol_to_list (sym, list_in_scope);
+             break;
+           }
+         attr = dwarf_attr (die, DW_AT_location);
+         if (attr)
+           {
+             attr2 = dwarf_attr (die, DW_AT_external);
+             if (attr2 && (DW_UNSND (attr2) != 0))
+               {
+                  /* Support the .debug_loc offsets */
+                  if (attr_form_is_block (attr))
+                    {
+                     SYMBOL_VALUE_ADDRESS (sym) =
+                       decode_locdesc (DW_BLOCK (attr), objfile, cu_header);
+                    }
+                  else if (attr->form == DW_FORM_data4
+                           || attr->form == DW_FORM_data8)
+                    {
+                      complain (&dwarf2_complex_location_expr);
+                    }
+                  else
+                    {
+                      complain (&dwarf2_invalid_attrib_class, "DW_AT_location",
+                                "external variable");
+                    }
+                 add_symbol_to_list (sym, &global_symbols);
+
+                 /* In shared libraries the address of the variable
+                    in the location descriptor might still be relocatable,
+                    so its value could be zero.
+                    Enter the symbol as a LOC_UNRESOLVED symbol, if its
+                    value is zero, the address of the variable will then
+                    be determined from the minimal symbol table whenever
+                    the variable is referenced.  */
+                 if (SYMBOL_VALUE_ADDRESS (sym))
+                   {
+                     fixup_symbol_section (sym, objfile);
+                     SYMBOL_VALUE_ADDRESS (sym) +=
+                       ANOFFSET (objfile->section_offsets,
+                                 SYMBOL_SECTION (sym));
+                     SYMBOL_CLASS (sym) = LOC_STATIC;
+                   }
+                 else
+                   SYMBOL_CLASS (sym) = LOC_UNRESOLVED;
+               }
+             else
+               {
+                  /* Support the .debug_loc offsets */
+                  if (attr_form_is_block (attr))
+                    {
+                     SYMBOL_VALUE (sym) = addr =
+                       decode_locdesc (DW_BLOCK (attr), objfile, cu_header);
+                    }
+                  else if (attr->form == DW_FORM_data4
+                           || attr->form == DW_FORM_data8)
+                    {
+                      complain (&dwarf2_complex_location_expr);
+                    }
+                  else
+                    {
+                      complain (&dwarf2_invalid_attrib_class, "DW_AT_location",
+                                "external variable");
+                      addr = 0;
+                    }
+                 add_symbol_to_list (sym, list_in_scope);
+                 if (optimized_out)
+                   {
+                     SYMBOL_CLASS (sym) = LOC_OPTIMIZED_OUT;
+                   }
+                 else if (isreg)
+                   {
+                     SYMBOL_CLASS (sym) = LOC_REGISTER;
+                     SYMBOL_VALUE (sym) = 
+                       DWARF2_REG_TO_REGNUM (SYMBOL_VALUE (sym));
+                   }
+                 else if (offreg)
+                   {
+                     SYMBOL_CLASS (sym) = LOC_BASEREG;
+                     SYMBOL_BASEREG (sym) = DWARF2_REG_TO_REGNUM (basereg);
+                   }
+                 else if (islocal)
+                   {
+                     SYMBOL_CLASS (sym) = LOC_LOCAL;
+                   }
+                 else
+                   {
+                     fixup_symbol_section (sym, objfile);
+                     SYMBOL_VALUE_ADDRESS (sym) =
+                       addr + ANOFFSET (objfile->section_offsets,
+                                        SYMBOL_SECTION (sym));
+                     SYMBOL_CLASS (sym) = LOC_STATIC;
+                   }
+               }
+           }
+         else
+           {
+             /* We do not know the address of this symbol.
+                If it is an external symbol and we have type information
+                for it, enter the symbol as a LOC_UNRESOLVED symbol.
+                The address of the variable will then be determined from
+                the minimal symbol table whenever the variable is
+                referenced.  */
+             attr2 = dwarf_attr (die, DW_AT_external);
+             if (attr2 && (DW_UNSND (attr2) != 0)
+                 && dwarf_attr (die, DW_AT_type) != NULL)
+               {
+                 SYMBOL_CLASS (sym) = LOC_UNRESOLVED;
+                 add_symbol_to_list (sym, &global_symbols);
+               }
+           }
+         break;
+       case DW_TAG_formal_parameter:
+         attr = dwarf_attr (die, DW_AT_location);
+         if (attr)
+           {
+             SYMBOL_VALUE (sym) =
+               decode_locdesc (DW_BLOCK (attr), objfile, cu_header);
+             if (isreg)
+               {
+                 SYMBOL_CLASS (sym) = LOC_REGPARM;
+                 SYMBOL_VALUE (sym) = 
+                   DWARF2_REG_TO_REGNUM (SYMBOL_VALUE (sym));
+               }
+             else if (offreg)
+               {
+                 if (isderef)
+                   {
+                     if (basereg != frame_base_reg)
+                       complain (&dwarf2_complex_location_expr);
+                     SYMBOL_CLASS (sym) = LOC_REF_ARG;
+                   }
+                 else
+                   {
+                     SYMBOL_CLASS (sym) = LOC_BASEREG_ARG;
+                     SYMBOL_BASEREG (sym) = DWARF2_REG_TO_REGNUM (basereg);
+                   }
+               }
+             else
+               {
+                 SYMBOL_CLASS (sym) = LOC_ARG;
+               }
+           }
+         attr = dwarf_attr (die, DW_AT_const_value);
+         if (attr)
+           {
+             dwarf2_const_value (attr, sym, objfile, cu_header);
+           }
+         add_symbol_to_list (sym, list_in_scope);
+         break;
+       case DW_TAG_unspecified_parameters:
+         /* From varargs functions; gdb doesn't seem to have any
+            interest in this information, so just ignore it for now.
+            (FIXME?) */
+         break;
+       case DW_TAG_class_type:
+       case DW_TAG_structure_type:
+       case DW_TAG_union_type:
+       case DW_TAG_enumeration_type:
+         SYMBOL_CLASS (sym) = LOC_TYPEDEF;
+         SYMBOL_NAMESPACE (sym) = STRUCT_NAMESPACE;
+         add_symbol_to_list (sym, list_in_scope);
+
+         /* The semantics of C++ state that "struct foo { ... }" also
+            defines a typedef for "foo". Synthesize a typedef symbol so
+            that "ptype foo" works as expected.  */
+         if (cu_language == language_cplus)
+           {
+             struct symbol *typedef_sym = (struct symbol *)
+             obstack_alloc (&objfile->symbol_obstack,
+                            sizeof (struct symbol));
+             *typedef_sym = *sym;
+             SYMBOL_NAMESPACE (typedef_sym) = VAR_NAMESPACE;
+             if (TYPE_NAME (SYMBOL_TYPE (sym)) == 0)
+               TYPE_NAME (SYMBOL_TYPE (sym)) =
+                 obsavestring (SYMBOL_NAME (sym),
+                               strlen (SYMBOL_NAME (sym)),
+                               &objfile->type_obstack);
+             add_symbol_to_list (typedef_sym, list_in_scope);
+           }
+         break;
+       case DW_TAG_typedef:
+       case DW_TAG_base_type:
+         SYMBOL_CLASS (sym) = LOC_TYPEDEF;
+         SYMBOL_NAMESPACE (sym) = VAR_NAMESPACE;
+         add_symbol_to_list (sym, list_in_scope);
+         break;
+       case DW_TAG_enumerator:
+         attr = dwarf_attr (die, DW_AT_const_value);
+         if (attr)
+           {
+             dwarf2_const_value (attr, sym, objfile, cu_header);
+           }
+         add_symbol_to_list (sym, list_in_scope);
+         break;
+       default:
+         /* Not a tag we recognize.  Hopefully we aren't processing
+            trash data, but since we must specifically ignore things
+            we don't recognize, there is nothing else we should do at
+            this point. */
+         complain (&dwarf2_unsupported_tag, dwarf_tag_name (die->tag));
+         break;
+       }
+    }
+  return (sym);
+}
+
+/* Copy constant value from an attribute to a symbol.  */
+
+static void
+dwarf2_const_value (struct attribute *attr, struct symbol *sym,
+                   struct objfile *objfile,
+                   const struct comp_unit_head *cu_header)
+{
+  struct dwarf_block *blk;
+
+  switch (attr->form)
+    {
+    case DW_FORM_addr:
+      if (TYPE_LENGTH (SYMBOL_TYPE (sym)) != cu_header->addr_size)
+       complain (&dwarf2_const_value_length_mismatch, SYMBOL_NAME (sym),
+                 cu_header->addr_size, TYPE_LENGTH (SYMBOL_TYPE (sym)));
+      SYMBOL_VALUE_BYTES (sym) = (char *)
+       obstack_alloc (&objfile->symbol_obstack, cu_header->addr_size);
+      store_address (SYMBOL_VALUE_BYTES (sym), cu_header->addr_size,
+                    DW_ADDR (attr));
+      SYMBOL_CLASS (sym) = LOC_CONST_BYTES;
+      break;
+    case DW_FORM_block1:
+    case DW_FORM_block2:
+    case DW_FORM_block4:
+    case DW_FORM_block:
+      blk = DW_BLOCK (attr);
+      if (TYPE_LENGTH (SYMBOL_TYPE (sym)) != blk->size)
+       complain (&dwarf2_const_value_length_mismatch, SYMBOL_NAME (sym),
+                 blk->size, TYPE_LENGTH (SYMBOL_TYPE (sym)));
+      SYMBOL_VALUE_BYTES (sym) = (char *)
+       obstack_alloc (&objfile->symbol_obstack, blk->size);
+      memcpy (SYMBOL_VALUE_BYTES (sym), blk->data, blk->size);
+      SYMBOL_CLASS (sym) = LOC_CONST_BYTES;
+      break;
+
+      /* The DW_AT_const_value attributes are supposed to carry the
+        symbol's value "represented as it would be on the target
+        architecture."  By the time we get here, it's already been
+        converted to host endianness, so we just need to sign- or
+        zero-extend it as appropriate.  */
+    case DW_FORM_data1:
+      dwarf2_const_value_data (attr, sym, 8);
+      break;
+    case DW_FORM_data2:
+      dwarf2_const_value_data (attr, sym, 16);
+      break;
+    case DW_FORM_data4:
+      dwarf2_const_value_data (attr, sym, 32);
+      break;
+    case DW_FORM_data8:
+      dwarf2_const_value_data (attr, sym, 64);
+      break;
+
+    case DW_FORM_sdata:
+      SYMBOL_VALUE (sym) = DW_SND (attr);
+      SYMBOL_CLASS (sym) = LOC_CONST;
+      break;
+
+    case DW_FORM_udata:
+      SYMBOL_VALUE (sym) = DW_UNSND (attr);
+      SYMBOL_CLASS (sym) = LOC_CONST;
+      break;
+
+    default:
+      complain (&dwarf2_unsupported_const_value_attr,
+               dwarf_form_name (attr->form));
+      SYMBOL_VALUE (sym) = 0;
+      SYMBOL_CLASS (sym) = LOC_CONST;
+      break;
+    }
+}
+
+
+/* Given an attr with a DW_FORM_dataN value in host byte order, sign-
+   or zero-extend it as appropriate for the symbol's type.  */
+static void
+dwarf2_const_value_data (struct attribute *attr,
+                        struct symbol *sym,
+                        int bits)
+{
+  LONGEST l = DW_UNSND (attr);
+
+  if (bits < sizeof (l) * 8)
+    {
+      if (TYPE_UNSIGNED (SYMBOL_TYPE (sym)))
+       l &= ((LONGEST) 1 << bits) - 1;
+      else
+       l = (l << (sizeof (l) * 8 - bits)) >> (sizeof (l) * 8 - bits);
+    }
+
+  SYMBOL_VALUE (sym) = l;
+  SYMBOL_CLASS (sym) = LOC_CONST;
+}
+
+
+/* Return the type of the die in question using its DW_AT_type attribute.  */
+
+static struct type *
+die_type (struct die_info *die, struct objfile *objfile,
+         const struct comp_unit_head *cu_header)
+{
+  struct type *type;
+  struct attribute *type_attr;
+  struct die_info *type_die;
+  unsigned int ref;
+
+  type_attr = dwarf_attr (die, DW_AT_type);
+  if (!type_attr)
+    {
+      /* A missing DW_AT_type represents a void type.  */
+      return dwarf2_fundamental_type (objfile, FT_VOID);
+    }
+  else
+    {
+      ref = dwarf2_get_ref_die_offset (type_attr);
+      type_die = follow_die_ref (ref);
+      if (!type_die)
+       {
+         error ("Dwarf Error: Cannot find referent at offset %d.", ref);
+         return NULL;
+       }
+    }
+  type = tag_type_to_type (type_die, objfile, cu_header);
+  if (!type)
+    {
+      dump_die (type_die);
+      error ("Dwarf Error: Problem turning type die at offset into gdb type.");
+    }
+  return type;
+}
+
+/* Return the containing type of the die in question using its
+   DW_AT_containing_type attribute.  */
+
+static struct type *
+die_containing_type (struct die_info *die, struct objfile *objfile,
+                    const struct comp_unit_head *cu_header)
+{
+  struct type *type = NULL;
+  struct attribute *type_attr;
+  struct die_info *type_die = NULL;
+  unsigned int ref;
+
+  type_attr = dwarf_attr (die, DW_AT_containing_type);
+  if (type_attr)
+    {
+      ref = dwarf2_get_ref_die_offset (type_attr);
+      type_die = follow_die_ref (ref);
+      if (!type_die)
+       {
+         error ("Dwarf Error: Cannot find referent at offset %d.", ref);
+         return NULL;
+       }
+      type = tag_type_to_type (type_die, objfile, cu_header);
+    }
+  if (!type)
+    {
+      if (type_die)
+       dump_die (type_die);
+      error ("Dwarf Error: Problem turning containing type into gdb type.");
+    }
+  return type;
+}
+
+#if 0
+static struct type *
+type_at_offset (unsigned int offset, struct objfile *objfile)
+{
+  struct die_info *die;
+  struct type *type;
+
+  die = follow_die_ref (offset);
+  if (!die)
+    {
+      error ("Dwarf Error: Cannot find type referent at offset %d.", offset);
+      return NULL;
+    }
+  type = tag_type_to_type (die, objfile);
+  return type;
+}
+#endif
+
+static struct type *
+tag_type_to_type (struct die_info *die, struct objfile *objfile,
+                 const struct comp_unit_head *cu_header)
+{
+  if (die->type)
+    {
+      return die->type;
+    }
+  else
+    {
+      read_type_die (die, objfile, cu_header);
+      if (!die->type)
+       {
+         dump_die (die);
+         error ("Dwarf Error: Cannot find type of die.");
+       }
+      return die->type;
+    }
+}
+
+static void
+read_type_die (struct die_info *die, struct objfile *objfile,
+              const struct comp_unit_head *cu_header)
+{
+  switch (die->tag)
+    {
+    case DW_TAG_class_type:
+    case DW_TAG_structure_type:
+    case DW_TAG_union_type:
+      read_structure_scope (die, objfile, cu_header);
+      break;
+    case DW_TAG_enumeration_type:
+      read_enumeration (die, objfile, cu_header);
+      break;
+    case DW_TAG_subprogram:
+    case DW_TAG_subroutine_type:
+      read_subroutine_type (die, objfile, cu_header);
+      break;
+    case DW_TAG_array_type:
+      read_array_type (die, objfile, cu_header);
+      break;
+    case DW_TAG_pointer_type:
+      read_tag_pointer_type (die, objfile, cu_header);
+      break;
+    case DW_TAG_ptr_to_member_type:
+      read_tag_ptr_to_member_type (die, objfile, cu_header);
+      break;
+    case DW_TAG_reference_type:
+      read_tag_reference_type (die, objfile, cu_header);
+      break;
+    case DW_TAG_const_type:
+      read_tag_const_type (die, objfile, cu_header);
+      break;
+    case DW_TAG_volatile_type:
+      read_tag_volatile_type (die, objfile, cu_header);
+      break;
+    case DW_TAG_string_type:
+      read_tag_string_type (die, objfile);
+      break;
+    case DW_TAG_typedef:
+      read_typedef (die, objfile, cu_header);
+      break;
+    case DW_TAG_base_type:
+      read_base_type (die, objfile);
+      break;
+    default:
+      complain (&dwarf2_unexpected_tag, dwarf_tag_name (die->tag));
+      break;
+    }
+}
+
+static struct type *
+dwarf_base_type (int encoding, int size, struct objfile *objfile)
+{
+  /* FIXME - this should not produce a new (struct type *)
+     every time.  It should cache base types.  */
+  struct type *type;
+  switch (encoding)
+    {
+    case DW_ATE_address:
+      type = dwarf2_fundamental_type (objfile, FT_VOID);
+      return type;
+    case DW_ATE_boolean:
+      type = dwarf2_fundamental_type (objfile, FT_BOOLEAN);
+      return type;
+    case DW_ATE_complex_float:
+      if (size == 16)
+       {
+         type = dwarf2_fundamental_type (objfile, FT_DBL_PREC_COMPLEX);
+       }
+      else
+       {
+         type = dwarf2_fundamental_type (objfile, FT_COMPLEX);
+       }
+      return type;
+    case DW_ATE_float:
+      if (size == 8)
+       {
+         type = dwarf2_fundamental_type (objfile, FT_DBL_PREC_FLOAT);
+       }
+      else
+       {
+         type = dwarf2_fundamental_type (objfile, FT_FLOAT);
+       }
+      return type;
+    case DW_ATE_signed:
+      switch (size)
+       {
+       case 1:
+         type = dwarf2_fundamental_type (objfile, FT_SIGNED_CHAR);
+         break;
+       case 2:
+         type = dwarf2_fundamental_type (objfile, FT_SIGNED_SHORT);
+         break;
+       default:
+       case 4:
+         type = dwarf2_fundamental_type (objfile, FT_SIGNED_INTEGER);
+         break;
+       }
+      return type;
+    case DW_ATE_signed_char:
+      type = dwarf2_fundamental_type (objfile, FT_SIGNED_CHAR);
+      return type;
+    case DW_ATE_unsigned:
+      switch (size)
+       {
+       case 1:
+         type = dwarf2_fundamental_type (objfile, FT_UNSIGNED_CHAR);
+         break;
+       case 2:
+         type = dwarf2_fundamental_type (objfile, FT_UNSIGNED_SHORT);
+         break;
+       default:
+       case 4:
+         type = dwarf2_fundamental_type (objfile, FT_UNSIGNED_INTEGER);
+         break;
+       }
+      return type;
+    case DW_ATE_unsigned_char:
+      type = dwarf2_fundamental_type (objfile, FT_UNSIGNED_CHAR);
+      return type;
+    default:
+      type = dwarf2_fundamental_type (objfile, FT_SIGNED_INTEGER);
+      return type;
+    }
+}
+
+#if 0
+struct die_info *
+copy_die (struct die_info *old_die)
+{
+  struct die_info *new_die;
+  int i, num_attrs;
+
+  new_die = (struct die_info *) xmalloc (sizeof (struct die_info));
+  memset (new_die, 0, sizeof (struct die_info));
+
+  new_die->tag = old_die->tag;
+  new_die->has_children = old_die->has_children;
+  new_die->abbrev = old_die->abbrev;
+  new_die->offset = old_die->offset;
+  new_die->type = NULL;
+
+  num_attrs = old_die->num_attrs;
+  new_die->num_attrs = num_attrs;
+  new_die->attrs = (struct attribute *)
+    xmalloc (num_attrs * sizeof (struct attribute));
+
+  for (i = 0; i < old_die->num_attrs; ++i)
+    {
+      new_die->attrs[i].name = old_die->attrs[i].name;
+      new_die->attrs[i].form = old_die->attrs[i].form;
+      new_die->attrs[i].u.addr = old_die->attrs[i].u.addr;
+    }
+
+  new_die->next = NULL;
+  return new_die;
+}
+#endif
+
+/* Return sibling of die, NULL if no sibling.  */
+
+static struct die_info *
+sibling_die (struct die_info *die)
+{
+  int nesting_level = 0;
+
+  if (!die->has_children)
+    {
+      if (die->next && (die->next->tag == 0))
+       {
+         return NULL;
+       }
+      else
+       {
+         return die->next;
+       }
+    }
+  else
+    {
+      do
+       {
+         if (die->has_children)
+           {
+             nesting_level++;
+           }
+         if (die->tag == 0)
+           {
+             nesting_level--;
+           }
+         die = die->next;
+       }
+      while (nesting_level);
+      if (die && (die->tag == 0))
+       {
+         return NULL;
+       }
+      else
+       {
+         return die;
+       }
+    }
+}
+
+/* Get linkage name of a die, return NULL if not found.  */
+
+static char *
+dwarf2_linkage_name (struct die_info *die)
+{
+  struct attribute *attr;
+
+  attr = dwarf_attr (die, DW_AT_MIPS_linkage_name);
+  if (attr && DW_STRING (attr))
+    return DW_STRING (attr);
+  attr = dwarf_attr (die, DW_AT_name);
+  if (attr && DW_STRING (attr))
+    return DW_STRING (attr);
+  return NULL;
+}
+
+/* Convert a DIE tag into its string name.  */
+
+static char *
+dwarf_tag_name (register unsigned tag)
+{
+  switch (tag)
+    {
+    case DW_TAG_padding:
+      return "DW_TAG_padding";
+    case DW_TAG_array_type:
+      return "DW_TAG_array_type";
+    case DW_TAG_class_type:
+      return "DW_TAG_class_type";
+    case DW_TAG_entry_point:
+      return "DW_TAG_entry_point";
+    case DW_TAG_enumeration_type:
+      return "DW_TAG_enumeration_type";
+    case DW_TAG_formal_parameter:
+      return "DW_TAG_formal_parameter";
+    case DW_TAG_imported_declaration:
+      return "DW_TAG_imported_declaration";
+    case DW_TAG_label:
+      return "DW_TAG_label";
+    case DW_TAG_lexical_block:
+      return "DW_TAG_lexical_block";
+    case DW_TAG_member:
+      return "DW_TAG_member";
+    case DW_TAG_pointer_type:
+      return "DW_TAG_pointer_type";
+    case DW_TAG_reference_type:
+      return "DW_TAG_reference_type";
+    case DW_TAG_compile_unit:
+      return "DW_TAG_compile_unit";
+    case DW_TAG_string_type:
+      return "DW_TAG_string_type";
+    case DW_TAG_structure_type:
+      return "DW_TAG_structure_type";
+    case DW_TAG_subroutine_type:
+      return "DW_TAG_subroutine_type";
+    case DW_TAG_typedef:
+      return "DW_TAG_typedef";
+    case DW_TAG_union_type:
+      return "DW_TAG_union_type";
+    case DW_TAG_unspecified_parameters:
+      return "DW_TAG_unspecified_parameters";
+    case DW_TAG_variant:
+      return "DW_TAG_variant";
+    case DW_TAG_common_block:
+      return "DW_TAG_common_block";
+    case DW_TAG_common_inclusion:
+      return "DW_TAG_common_inclusion";
+    case DW_TAG_inheritance:
+      return "DW_TAG_inheritance";
+    case DW_TAG_inlined_subroutine:
+      return "DW_TAG_inlined_subroutine";
+    case DW_TAG_module:
+      return "DW_TAG_module";
+    case DW_TAG_ptr_to_member_type:
+      return "DW_TAG_ptr_to_member_type";
+    case DW_TAG_set_type:
+      return "DW_TAG_set_type";
+    case DW_TAG_subrange_type:
+      return "DW_TAG_subrange_type";
+    case DW_TAG_with_stmt:
+      return "DW_TAG_with_stmt";
+    case DW_TAG_access_declaration:
+      return "DW_TAG_access_declaration";
+    case DW_TAG_base_type:
+      return "DW_TAG_base_type";
+    case DW_TAG_catch_block:
+      return "DW_TAG_catch_block";
+    case DW_TAG_const_type:
+      return "DW_TAG_const_type";
+    case DW_TAG_constant:
+      return "DW_TAG_constant";
+    case DW_TAG_enumerator:
+      return "DW_TAG_enumerator";
+    case DW_TAG_file_type:
+      return "DW_TAG_file_type";
+    case DW_TAG_friend:
+      return "DW_TAG_friend";
+    case DW_TAG_namelist:
+      return "DW_TAG_namelist";
+    case DW_TAG_namelist_item:
+      return "DW_TAG_namelist_item";
+    case DW_TAG_packed_type:
+      return "DW_TAG_packed_type";
+    case DW_TAG_subprogram:
+      return "DW_TAG_subprogram";
+    case DW_TAG_template_type_param:
+      return "DW_TAG_template_type_param";
+    case DW_TAG_template_value_param:
+      return "DW_TAG_template_value_param";
+    case DW_TAG_thrown_type:
+      return "DW_TAG_thrown_type";
+    case DW_TAG_try_block:
+      return "DW_TAG_try_block";
+    case DW_TAG_variant_part:
+      return "DW_TAG_variant_part";
+    case DW_TAG_variable:
+      return "DW_TAG_variable";
+    case DW_TAG_volatile_type:
+      return "DW_TAG_volatile_type";
+    case DW_TAG_MIPS_loop:
+      return "DW_TAG_MIPS_loop";
+    case DW_TAG_format_label:
+      return "DW_TAG_format_label";
+    case DW_TAG_function_template:
+      return "DW_TAG_function_template";
+    case DW_TAG_class_template:
+      return "DW_TAG_class_template";
+    default:
+      return "DW_TAG_<unknown>";
+    }
+}
+
+/* Convert a DWARF attribute code into its string name.  */
+
+static char *
+dwarf_attr_name (register unsigned attr)
+{
+  switch (attr)
+    {
+    case DW_AT_sibling:
+      return "DW_AT_sibling";
+    case DW_AT_location:
+      return "DW_AT_location";
+    case DW_AT_name:
+      return "DW_AT_name";
+    case DW_AT_ordering:
+      return "DW_AT_ordering";
+    case DW_AT_subscr_data:
+      return "DW_AT_subscr_data";
+    case DW_AT_byte_size:
+      return "DW_AT_byte_size";
+    case DW_AT_bit_offset:
+      return "DW_AT_bit_offset";
+    case DW_AT_bit_size:
+      return "DW_AT_bit_size";
+    case DW_AT_element_list:
+      return "DW_AT_element_list";
+    case DW_AT_stmt_list:
+      return "DW_AT_stmt_list";
+    case DW_AT_low_pc:
+      return "DW_AT_low_pc";
+    case DW_AT_high_pc:
+      return "DW_AT_high_pc";
+    case DW_AT_language:
+      return "DW_AT_language";
+    case DW_AT_member:
+      return "DW_AT_member";
+    case DW_AT_discr:
+      return "DW_AT_discr";
+    case DW_AT_discr_value:
+      return "DW_AT_discr_value";
+    case DW_AT_visibility:
+      return "DW_AT_visibility";
+    case DW_AT_import:
+      return "DW_AT_import";
+    case DW_AT_string_length:
+      return "DW_AT_string_length";
+    case DW_AT_common_reference:
+      return "DW_AT_common_reference";
+    case DW_AT_comp_dir:
+      return "DW_AT_comp_dir";
+    case DW_AT_const_value:
+      return "DW_AT_const_value";
+    case DW_AT_containing_type:
+      return "DW_AT_containing_type";
+    case DW_AT_default_value:
+      return "DW_AT_default_value";
+    case DW_AT_inline:
+      return "DW_AT_inline";
+    case DW_AT_is_optional:
+      return "DW_AT_is_optional";
+    case DW_AT_lower_bound:
+      return "DW_AT_lower_bound";
+    case DW_AT_producer:
+      return "DW_AT_producer";
+    case DW_AT_prototyped:
+      return "DW_AT_prototyped";
+    case DW_AT_return_addr:
+      return "DW_AT_return_addr";
+    case DW_AT_start_scope:
+      return "DW_AT_start_scope";
+    case DW_AT_stride_size:
+      return "DW_AT_stride_size";
+    case DW_AT_upper_bound:
+      return "DW_AT_upper_bound";
+    case DW_AT_abstract_origin:
+      return "DW_AT_abstract_origin";
+    case DW_AT_accessibility:
+      return "DW_AT_accessibility";
+    case DW_AT_address_class:
+      return "DW_AT_address_class";
+    case DW_AT_artificial:
+      return "DW_AT_artificial";
+    case DW_AT_base_types:
+      return "DW_AT_base_types";
+    case DW_AT_calling_convention:
+      return "DW_AT_calling_convention";
+    case DW_AT_count:
+      return "DW_AT_count";
+    case DW_AT_data_member_location:
+      return "DW_AT_data_member_location";
+    case DW_AT_decl_column:
+      return "DW_AT_decl_column";
+    case DW_AT_decl_file:
+      return "DW_AT_decl_file";
+    case DW_AT_decl_line:
+      return "DW_AT_decl_line";
+    case DW_AT_declaration:
+      return "DW_AT_declaration";
+    case DW_AT_discr_list:
+      return "DW_AT_discr_list";
+    case DW_AT_encoding:
+      return "DW_AT_encoding";
+    case DW_AT_external:
+      return "DW_AT_external";
+    case DW_AT_frame_base:
+      return "DW_AT_frame_base";
+    case DW_AT_friend:
+      return "DW_AT_friend";
+    case DW_AT_identifier_case:
+      return "DW_AT_identifier_case";
+    case DW_AT_macro_info:
+      return "DW_AT_macro_info";
+    case DW_AT_namelist_items:
+      return "DW_AT_namelist_items";
+    case DW_AT_priority:
+      return "DW_AT_priority";
+    case DW_AT_segment:
+      return "DW_AT_segment";
+    case DW_AT_specification:
+      return "DW_AT_specification";
+    case DW_AT_static_link:
+      return "DW_AT_static_link";
+    case DW_AT_type:
+      return "DW_AT_type";
+    case DW_AT_use_location:
+      return "DW_AT_use_location";
+    case DW_AT_variable_parameter:
+      return "DW_AT_variable_parameter";
+    case DW_AT_virtuality:
+      return "DW_AT_virtuality";
+    case DW_AT_vtable_elem_location:
+      return "DW_AT_vtable_elem_location";
+
+#ifdef MIPS
+    case DW_AT_MIPS_fde:
+      return "DW_AT_MIPS_fde";
+    case DW_AT_MIPS_loop_begin:
+      return "DW_AT_MIPS_loop_begin";
+    case DW_AT_MIPS_tail_loop_begin:
+      return "DW_AT_MIPS_tail_loop_begin";
+    case DW_AT_MIPS_epilog_begin:
+      return "DW_AT_MIPS_epilog_begin";
+    case DW_AT_MIPS_loop_unroll_factor:
+      return "DW_AT_MIPS_loop_unroll_factor";
+    case DW_AT_MIPS_software_pipeline_depth:
+      return "DW_AT_MIPS_software_pipeline_depth";
+    case DW_AT_MIPS_linkage_name:
+      return "DW_AT_MIPS_linkage_name";
+#endif
+
+    case DW_AT_sf_names:
+      return "DW_AT_sf_names";
+    case DW_AT_src_info:
+      return "DW_AT_src_info";
+    case DW_AT_mac_info:
+      return "DW_AT_mac_info";
+    case DW_AT_src_coords:
+      return "DW_AT_src_coords";
+    case DW_AT_body_begin:
+      return "DW_AT_body_begin";
+    case DW_AT_body_end:
+      return "DW_AT_body_end";
+    case DW_AT_GNU_vector:
+      return "DW_AT_GNU_vector";
+    default:
+      return "DW_AT_<unknown>";
+    }
+}
+
+/* Convert a DWARF value form code into its string name.  */
+
+static char *
+dwarf_form_name (register unsigned form)
+{
+  switch (form)
+    {
+    case DW_FORM_addr:
+      return "DW_FORM_addr";
+    case DW_FORM_block2:
+      return "DW_FORM_block2";
+    case DW_FORM_block4:
+      return "DW_FORM_block4";
+    case DW_FORM_data2:
+      return "DW_FORM_data2";
+    case DW_FORM_data4:
+      return "DW_FORM_data4";
+    case DW_FORM_data8:
+      return "DW_FORM_data8";
+    case DW_FORM_string:
+      return "DW_FORM_string";
+    case DW_FORM_block:
+      return "DW_FORM_block";
+    case DW_FORM_block1:
+      return "DW_FORM_block1";
+    case DW_FORM_data1:
+      return "DW_FORM_data1";
+    case DW_FORM_flag:
+      return "DW_FORM_flag";
+    case DW_FORM_sdata:
+      return "DW_FORM_sdata";
+    case DW_FORM_strp:
+      return "DW_FORM_strp";
+    case DW_FORM_udata:
+      return "DW_FORM_udata";
+    case DW_FORM_ref_addr:
+      return "DW_FORM_ref_addr";
+    case DW_FORM_ref1:
+      return "DW_FORM_ref1";
+    case DW_FORM_ref2:
+      return "DW_FORM_ref2";
+    case DW_FORM_ref4:
+      return "DW_FORM_ref4";
+    case DW_FORM_ref8:
+      return "DW_FORM_ref8";
+    case DW_FORM_ref_udata:
+      return "DW_FORM_ref_udata";
+    case DW_FORM_indirect:
+      return "DW_FORM_indirect";
+    default:
+      return "DW_FORM_<unknown>";
+    }
+}
+
+/* Convert a DWARF stack opcode into its string name.  */
+
+static char *
+dwarf_stack_op_name (register unsigned op)
+{
+  switch (op)
+    {
+    case DW_OP_addr:
+      return "DW_OP_addr";
+    case DW_OP_deref:
+      return "DW_OP_deref";
+    case DW_OP_const1u:
+      return "DW_OP_const1u";
+    case DW_OP_const1s:
+      return "DW_OP_const1s";
+    case DW_OP_const2u:
+      return "DW_OP_const2u";
+    case DW_OP_const2s:
+      return "DW_OP_const2s";
+    case DW_OP_const4u:
+      return "DW_OP_const4u";
+    case DW_OP_const4s:
+      return "DW_OP_const4s";
+    case DW_OP_const8u:
+      return "DW_OP_const8u";
+    case DW_OP_const8s:
+      return "DW_OP_const8s";
+    case DW_OP_constu:
+      return "DW_OP_constu";
+    case DW_OP_consts:
+      return "DW_OP_consts";
+    case DW_OP_dup:
+      return "DW_OP_dup";
+    case DW_OP_drop:
+      return "DW_OP_drop";
+    case DW_OP_over:
+      return "DW_OP_over";
+    case DW_OP_pick:
+      return "DW_OP_pick";
+    case DW_OP_swap:
+      return "DW_OP_swap";
+    case DW_OP_rot:
+      return "DW_OP_rot";
+    case DW_OP_xderef:
+      return "DW_OP_xderef";
+    case DW_OP_abs:
+      return "DW_OP_abs";
+    case DW_OP_and:
+      return "DW_OP_and";
+    case DW_OP_div:
+      return "DW_OP_div";
+    case DW_OP_minus:
+      return "DW_OP_minus";
+    case DW_OP_mod:
+      return "DW_OP_mod";
+    case DW_OP_mul:
+      return "DW_OP_mul";
+    case DW_OP_neg:
+      return "DW_OP_neg";
+    case DW_OP_not:
+      return "DW_OP_not";
+    case DW_OP_or:
+      return "DW_OP_or";
+    case DW_OP_plus:
+      return "DW_OP_plus";
+    case DW_OP_plus_uconst:
+      return "DW_OP_plus_uconst";
+    case DW_OP_shl:
+      return "DW_OP_shl";
+    case DW_OP_shr:
+      return "DW_OP_shr";
+    case DW_OP_shra:
+      return "DW_OP_shra";
+    case DW_OP_xor:
+      return "DW_OP_xor";
+    case DW_OP_bra:
+      return "DW_OP_bra";
+    case DW_OP_eq:
+      return "DW_OP_eq";
+    case DW_OP_ge:
+      return "DW_OP_ge";
+    case DW_OP_gt:
+      return "DW_OP_gt";
+    case DW_OP_le:
+      return "DW_OP_le";
+    case DW_OP_lt:
+      return "DW_OP_lt";
+    case DW_OP_ne:
+      return "DW_OP_ne";
+    case DW_OP_skip:
+      return "DW_OP_skip";
+    case DW_OP_lit0:
+      return "DW_OP_lit0";
+    case DW_OP_lit1:
+      return "DW_OP_lit1";
+    case DW_OP_lit2:
+      return "DW_OP_lit2";
+    case DW_OP_lit3:
+      return "DW_OP_lit3";
+    case DW_OP_lit4:
+      return "DW_OP_lit4";
+    case DW_OP_lit5:
+      return "DW_OP_lit5";
+    case DW_OP_lit6:
+      return "DW_OP_lit6";
+    case DW_OP_lit7:
+      return "DW_OP_lit7";
+    case DW_OP_lit8:
+      return "DW_OP_lit8";
+    case DW_OP_lit9:
+      return "DW_OP_lit9";
+    case DW_OP_lit10:
+      return "DW_OP_lit10";
+    case DW_OP_lit11:
+      return "DW_OP_lit11";
+    case DW_OP_lit12:
+      return "DW_OP_lit12";
+    case DW_OP_lit13:
+      return "DW_OP_lit13";
+    case DW_OP_lit14:
+      return "DW_OP_lit14";
+    case DW_OP_lit15:
+      return "DW_OP_lit15";
+    case DW_OP_lit16:
+      return "DW_OP_lit16";
+    case DW_OP_lit17:
+      return "DW_OP_lit17";
+    case DW_OP_lit18:
+      return "DW_OP_lit18";
+    case DW_OP_lit19:
+      return "DW_OP_lit19";
+    case DW_OP_lit20:
+      return "DW_OP_lit20";
+    case DW_OP_lit21:
+      return "DW_OP_lit21";
+    case DW_OP_lit22:
+      return "DW_OP_lit22";
+    case DW_OP_lit23:
+      return "DW_OP_lit23";
+    case DW_OP_lit24:
+      return "DW_OP_lit24";
+    case DW_OP_lit25:
+      return "DW_OP_lit25";
+    case DW_OP_lit26:
+      return "DW_OP_lit26";
+    case DW_OP_lit27:
+      return "DW_OP_lit27";
+    case DW_OP_lit28:
+      return "DW_OP_lit28";
+    case DW_OP_lit29:
+      return "DW_OP_lit29";
+    case DW_OP_lit30:
+      return "DW_OP_lit30";
+    case DW_OP_lit31:
+      return "DW_OP_lit31";
+    case DW_OP_reg0:
+      return "DW_OP_reg0";
+    case DW_OP_reg1:
+      return "DW_OP_reg1";
+    case DW_OP_reg2:
+      return "DW_OP_reg2";
+    case DW_OP_reg3:
+      return "DW_OP_reg3";
+    case DW_OP_reg4:
+      return "DW_OP_reg4";
+    case DW_OP_reg5:
+      return "DW_OP_reg5";
+    case DW_OP_reg6:
+      return "DW_OP_reg6";
+    case DW_OP_reg7:
+      return "DW_OP_reg7";
+    case DW_OP_reg8:
+      return "DW_OP_reg8";
+    case DW_OP_reg9:
+      return "DW_OP_reg9";
+    case DW_OP_reg10:
+      return "DW_OP_reg10";
+    case DW_OP_reg11:
+      return "DW_OP_reg11";
+    case DW_OP_reg12:
+      return "DW_OP_reg12";
+    case DW_OP_reg13:
+      return "DW_OP_reg13";
+    case DW_OP_reg14:
+      return "DW_OP_reg14";
+    case DW_OP_reg15:
+      return "DW_OP_reg15";
+    case DW_OP_reg16:
+      return "DW_OP_reg16";
+    case DW_OP_reg17:
+      return "DW_OP_reg17";
+    case DW_OP_reg18:
+      return "DW_OP_reg18";
+    case DW_OP_reg19:
+      return "DW_OP_reg19";
+    case DW_OP_reg20:
+      return "DW_OP_reg20";
+    case DW_OP_reg21:
+      return "DW_OP_reg21";
+    case DW_OP_reg22:
+      return "DW_OP_reg22";
+    case DW_OP_reg23:
+      return "DW_OP_reg23";
+    case DW_OP_reg24:
+      return "DW_OP_reg24";
+    case DW_OP_reg25:
+      return "DW_OP_reg25";
+    case DW_OP_reg26:
+      return "DW_OP_reg26";
+    case DW_OP_reg27:
+      return "DW_OP_reg27";
+    case DW_OP_reg28:
+      return "DW_OP_reg28";
+    case DW_OP_reg29:
+      return "DW_OP_reg29";
+    case DW_OP_reg30:
+      return "DW_OP_reg30";
+    case DW_OP_reg31:
+      return "DW_OP_reg31";
+    case DW_OP_breg0:
+      return "DW_OP_breg0";
+    case DW_OP_breg1:
+      return "DW_OP_breg1";
+    case DW_OP_breg2:
+      return "DW_OP_breg2";
+    case DW_OP_breg3:
+      return "DW_OP_breg3";
+    case DW_OP_breg4:
+      return "DW_OP_breg4";
+    case DW_OP_breg5:
+      return "DW_OP_breg5";
+    case DW_OP_breg6:
+      return "DW_OP_breg6";
+    case DW_OP_breg7:
+      return "DW_OP_breg7";
+    case DW_OP_breg8:
+      return "DW_OP_breg8";
+    case DW_OP_breg9:
+      return "DW_OP_breg9";
+    case DW_OP_breg10:
+      return "DW_OP_breg10";
+    case DW_OP_breg11:
+      return "DW_OP_breg11";
+    case DW_OP_breg12:
+      return "DW_OP_breg12";
+    case DW_OP_breg13:
+      return "DW_OP_breg13";
+    case DW_OP_breg14:
+      return "DW_OP_breg14";
+    case DW_OP_breg15:
+      return "DW_OP_breg15";
+    case DW_OP_breg16:
+      return "DW_OP_breg16";
+    case DW_OP_breg17:
+      return "DW_OP_breg17";
+    case DW_OP_breg18:
+      return "DW_OP_breg18";
+    case DW_OP_breg19:
+      return "DW_OP_breg19";
+    case DW_OP_breg20:
+      return "DW_OP_breg20";
+    case DW_OP_breg21:
+      return "DW_OP_breg21";
+    case DW_OP_breg22:
+      return "DW_OP_breg22";
+    case DW_OP_breg23:
+      return "DW_OP_breg23";
+    case DW_OP_breg24:
+      return "DW_OP_breg24";
+    case DW_OP_breg25:
+      return "DW_OP_breg25";
+    case DW_OP_breg26:
+      return "DW_OP_breg26";
+    case DW_OP_breg27:
+      return "DW_OP_breg27";
+    case DW_OP_breg28:
+      return "DW_OP_breg28";
+    case DW_OP_breg29:
+      return "DW_OP_breg29";
+    case DW_OP_breg30:
+      return "DW_OP_breg30";
+    case DW_OP_breg31:
+      return "DW_OP_breg31";
+    case DW_OP_regx:
+      return "DW_OP_regx";
+    case DW_OP_fbreg:
+      return "DW_OP_fbreg";
+    case DW_OP_bregx:
+      return "DW_OP_bregx";
+    case DW_OP_piece:
+      return "DW_OP_piece";
+    case DW_OP_deref_size:
+      return "DW_OP_deref_size";
+    case DW_OP_xderef_size:
+      return "DW_OP_xderef_size";
+    case DW_OP_nop:
+      return "DW_OP_nop";
+    default:
+      return "OP_<unknown>";
+    }
+}
+
+static char *
+dwarf_bool_name (unsigned mybool)
+{
+  if (mybool)
+    return "TRUE";
+  else
+    return "FALSE";
+}
+
+/* Convert a DWARF type code into its string name.  */
+
+static char *
+dwarf_type_encoding_name (register unsigned enc)
+{
+  switch (enc)
+    {
+    case DW_ATE_address:
+      return "DW_ATE_address";
+    case DW_ATE_boolean:
+      return "DW_ATE_boolean";
+    case DW_ATE_complex_float:
+      return "DW_ATE_complex_float";
+    case DW_ATE_float:
+      return "DW_ATE_float";
+    case DW_ATE_signed:
+      return "DW_ATE_signed";
+    case DW_ATE_signed_char:
+      return "DW_ATE_signed_char";
+    case DW_ATE_unsigned:
+      return "DW_ATE_unsigned";
+    case DW_ATE_unsigned_char:
+      return "DW_ATE_unsigned_char";
+    default:
+      return "DW_ATE_<unknown>";
+    }
+}
+
+/* Convert a DWARF call frame info operation to its string name. */
+
+#if 0
+static char *
+dwarf_cfi_name (register unsigned cfi_opc)
+{
+  switch (cfi_opc)
+    {
+    case DW_CFA_advance_loc:
+      return "DW_CFA_advance_loc";
+    case DW_CFA_offset:
+      return "DW_CFA_offset";
+    case DW_CFA_restore:
+      return "DW_CFA_restore";
+    case DW_CFA_nop:
+      return "DW_CFA_nop";
+    case DW_CFA_set_loc:
+      return "DW_CFA_set_loc";
+    case DW_CFA_advance_loc1:
+      return "DW_CFA_advance_loc1";
+    case DW_CFA_advance_loc2:
+      return "DW_CFA_advance_loc2";
+    case DW_CFA_advance_loc4:
+      return "DW_CFA_advance_loc4";
+    case DW_CFA_offset_extended:
+      return "DW_CFA_offset_extended";
+    case DW_CFA_restore_extended:
+      return "DW_CFA_restore_extended";
+    case DW_CFA_undefined:
+      return "DW_CFA_undefined";
+    case DW_CFA_same_value:
+      return "DW_CFA_same_value";
+    case DW_CFA_register:
+      return "DW_CFA_register";
+    case DW_CFA_remember_state:
+      return "DW_CFA_remember_state";
+    case DW_CFA_restore_state:
+      return "DW_CFA_restore_state";
+    case DW_CFA_def_cfa:
+      return "DW_CFA_def_cfa";
+    case DW_CFA_def_cfa_register:
+      return "DW_CFA_def_cfa_register";
+    case DW_CFA_def_cfa_offset:
+      return "DW_CFA_def_cfa_offset";
+
+    /* DWARF 3 */
+    case DW_CFA_def_cfa_expression:
+      return "DW_CFA_def_cfa_expression";
+    case DW_CFA_expression:
+      return "DW_CFA_expression";
+    case DW_CFA_offset_extended_sf:
+      return "DW_CFA_offset_extended_sf";
+    case DW_CFA_def_cfa_sf:
+      return "DW_CFA_def_cfa_sf";
+    case DW_CFA_def_cfa_offset_sf:
+      return "DW_CFA_def_cfa_offset_sf";
+
+      /* SGI/MIPS specific */
+    case DW_CFA_MIPS_advance_loc8:
+      return "DW_CFA_MIPS_advance_loc8";
+
+    /* GNU extensions */
+    case DW_CFA_GNU_window_save:
+      return "DW_CFA_GNU_window_save";
+    case DW_CFA_GNU_args_size:
+      return "DW_CFA_GNU_args_size";
+    case DW_CFA_GNU_negative_offset_extended:
+      return "DW_CFA_GNU_negative_offset_extended";
+
+    default:
+      return "DW_CFA_<unknown>";
+    }
+}
+#endif
+
+static void
+dump_die (struct die_info *die)
+{
+  unsigned int i;
+
+  fprintf_unfiltered (gdb_stderr, "Die: %s (abbrev = %d, offset = %d)\n",
+          dwarf_tag_name (die->tag), die->abbrev, die->offset);
+  fprintf_unfiltered (gdb_stderr, "\thas children: %s\n",
+          dwarf_bool_name (die->has_children));
+
+  fprintf_unfiltered (gdb_stderr, "\tattributes:\n");
+  for (i = 0; i < die->num_attrs; ++i)
+    {
+      fprintf_unfiltered (gdb_stderr, "\t\t%s (%s) ",
+              dwarf_attr_name (die->attrs[i].name),
+              dwarf_form_name (die->attrs[i].form));
+      switch (die->attrs[i].form)
+       {
+       case DW_FORM_ref_addr:
+       case DW_FORM_addr:
+         fprintf_unfiltered (gdb_stderr, "address: ");
+         print_address_numeric (DW_ADDR (&die->attrs[i]), 1, gdb_stderr);
+         break;
+       case DW_FORM_block2:
+       case DW_FORM_block4:
+       case DW_FORM_block:
+       case DW_FORM_block1:
+         fprintf_unfiltered (gdb_stderr, "block: size %d", DW_BLOCK (&die->attrs[i])->size);
+         break;
+       case DW_FORM_data1:
+       case DW_FORM_data2:
+       case DW_FORM_data4:
+       case DW_FORM_data8:
+       case DW_FORM_ref1:
+       case DW_FORM_ref2:
+       case DW_FORM_ref4:
+       case DW_FORM_udata:
+       case DW_FORM_sdata:
+         fprintf_unfiltered (gdb_stderr, "constant: %ld", DW_UNSND (&die->attrs[i]));
+         break;
+       case DW_FORM_string:
+       case DW_FORM_strp:
+         fprintf_unfiltered (gdb_stderr, "string: \"%s\"",
+                  DW_STRING (&die->attrs[i])
+                  ? DW_STRING (&die->attrs[i]) : "");
+         break;
+       case DW_FORM_flag:
+         if (DW_UNSND (&die->attrs[i]))
+           fprintf_unfiltered (gdb_stderr, "flag: TRUE");
+         else
+           fprintf_unfiltered (gdb_stderr, "flag: FALSE");
+         break;
+       case DW_FORM_indirect:
+         /* the reader will have reduced the indirect form to
+            the "base form" so this form should not occur */
+         fprintf_unfiltered (gdb_stderr, "unexpected attribute form: DW_FORM_indirect");
+         break;
+       default:
+         fprintf_unfiltered (gdb_stderr, "unsupported attribute form: %d.",
+                  die->attrs[i].form);
+       }
+      fprintf_unfiltered (gdb_stderr, "\n");
+    }
+}
+
+static void
+dump_die_list (struct die_info *die)
+{
+  while (die)
+    {
+      dump_die (die);
+      die = die->next;
+    }
+}
+
+static void
+store_in_ref_table (unsigned int offset, struct die_info *die)
+{
+  int h;
+  struct die_info *old;
+
+  h = (offset % REF_HASH_SIZE);
+  old = die_ref_table[h];
+  die->next_ref = old;
+  die_ref_table[h] = die;
+}
+
+
+static void
+dwarf2_empty_hash_tables (void)
+{
+  memset (die_ref_table, 0, sizeof (die_ref_table));
+}
+
+static unsigned int
+dwarf2_get_ref_die_offset (struct attribute *attr)
+{
+  unsigned int result = 0;
+
+  switch (attr->form)
+    {
+    case DW_FORM_ref_addr:
+      result = DW_ADDR (attr);
+      break;
+    case DW_FORM_ref1:
+    case DW_FORM_ref2:
+    case DW_FORM_ref4:
+    case DW_FORM_ref8:
+    case DW_FORM_ref_udata:
+      result = cu_header_offset + DW_UNSND (attr);
+      break;
+    default:
+      complain (&dwarf2_unsupported_die_ref_attr, dwarf_form_name (attr->form));
+    }
+  return result;
+}
+
+static struct die_info *
+follow_die_ref (unsigned int offset)
+{
+  struct die_info *die;
+  int h;
+
+  h = (offset % REF_HASH_SIZE);
+  die = die_ref_table[h];
+  while (die)
+    {
+      if (die->offset == offset)
+       {
+         return die;
+       }
+      die = die->next_ref;
+    }
+  return NULL;
+}
+
+static struct type *
+dwarf2_fundamental_type (struct objfile *objfile, int typeid)
+{
+  if (typeid < 0 || typeid >= FT_NUM_MEMBERS)
+    {
+      error ("Dwarf Error: internal error - invalid fundamental type id %d.",
+            typeid);
+    }
+
+  /* Look for this particular type in the fundamental type vector.  If
+     one is not found, create and install one appropriate for the
+     current language and the current target machine. */
+
+  if (ftypes[typeid] == NULL)
+    {
+      ftypes[typeid] = cu_language_defn->la_fund_type (objfile, typeid);
+    }
+
+  return (ftypes[typeid]);
+}
+
+/* Decode simple location descriptions.
+   Given a pointer to a dwarf block that defines a location, compute
+   the location and return the value.
+
+   FIXME: This is a kludge until we figure out a better
+   way to handle the location descriptions.
+   Gdb's design does not mesh well with the DWARF2 notion of a location
+   computing interpreter, which is a shame because the flexibility goes unused.
+   FIXME: Implement more operations as necessary.
+
+   A location description containing no operations indicates that the
+   object is optimized out. The global optimized_out flag is set for
+   those, the return value is meaningless.
+
+   When the result is a register number, the global isreg flag is set,
+   otherwise it is cleared.
+
+   When the result is a base register offset, the global offreg flag is set
+   and the register number is returned in basereg, otherwise it is cleared.
+
+   When the DW_OP_fbreg operation is encountered without a corresponding
+   DW_AT_frame_base attribute, the global islocal flag is set.
+   Hopefully the machine dependent code knows how to set up a virtual
+   frame pointer for the local references.
+
+   Note that stack[0] is unused except as a default error return.
+   Note that stack overflow is not yet handled.  */
+
+static CORE_ADDR
+decode_locdesc (struct dwarf_block *blk, struct objfile *objfile,
+               const struct comp_unit_head *cu_header)
+{
+  int i;
+  int size = blk->size;
+  char *data = blk->data;
+  CORE_ADDR stack[64];
+  int stacki;
+  unsigned int bytes_read, unsnd;
+  unsigned char op;
+
+  i = 0;
+  stacki = 0;
+  stack[stacki] = 0;
+  isreg = 0;
+  offreg = 0;
+  isderef = 0;
+  islocal = 0;
+  optimized_out = 1;
+
+  while (i < size)
+    {
+      optimized_out = 0;
+      op = data[i++];
+      switch (op)
+       {
+       case DW_OP_lit0:
+       case DW_OP_lit1:
+       case DW_OP_lit2:
+       case DW_OP_lit3:
+       case DW_OP_lit4:
+       case DW_OP_lit5:
+       case DW_OP_lit6:
+       case DW_OP_lit7:
+       case DW_OP_lit8:
+       case DW_OP_lit9:
+       case DW_OP_lit10:
+       case DW_OP_lit11:
+       case DW_OP_lit12:
+       case DW_OP_lit13:
+       case DW_OP_lit14:
+       case DW_OP_lit15:
+       case DW_OP_lit16:
+       case DW_OP_lit17:
+       case DW_OP_lit18:
+       case DW_OP_lit19:
+       case DW_OP_lit20:
+       case DW_OP_lit21:
+       case DW_OP_lit22:
+       case DW_OP_lit23:
+       case DW_OP_lit24:
+       case DW_OP_lit25:
+       case DW_OP_lit26:
+       case DW_OP_lit27:
+       case DW_OP_lit28:
+       case DW_OP_lit29:
+       case DW_OP_lit30:
+       case DW_OP_lit31:
+         stack[++stacki] = op - DW_OP_lit0;
+         break;
+
+       case DW_OP_reg0:
+       case DW_OP_reg1:
+       case DW_OP_reg2:
+       case DW_OP_reg3:
+       case DW_OP_reg4:
+       case DW_OP_reg5:
+       case DW_OP_reg6:
+       case DW_OP_reg7:
+       case DW_OP_reg8:
+       case DW_OP_reg9:
+       case DW_OP_reg10:
+       case DW_OP_reg11:
+       case DW_OP_reg12:
+       case DW_OP_reg13:
+       case DW_OP_reg14:
+       case DW_OP_reg15:
+       case DW_OP_reg16:
+       case DW_OP_reg17:
+       case DW_OP_reg18:
+       case DW_OP_reg19:
+       case DW_OP_reg20:
+       case DW_OP_reg21:
+       case DW_OP_reg22:
+       case DW_OP_reg23:
+       case DW_OP_reg24:
+       case DW_OP_reg25:
+       case DW_OP_reg26:
+       case DW_OP_reg27:
+       case DW_OP_reg28:
+       case DW_OP_reg29:
+       case DW_OP_reg30:
+       case DW_OP_reg31:
+         isreg = 1;
+         stack[++stacki] = op - DW_OP_reg0;
+         break;
+
+       case DW_OP_regx:
+         isreg = 1;
+         unsnd = read_unsigned_leb128 (NULL, (data + i), &bytes_read);
+         i += bytes_read;
+         stack[++stacki] = unsnd;
+         break;
+
+       case DW_OP_breg0:
+       case DW_OP_breg1:
+       case DW_OP_breg2:
+       case DW_OP_breg3:
+       case DW_OP_breg4:
+       case DW_OP_breg5:
+       case DW_OP_breg6:
+       case DW_OP_breg7:
+       case DW_OP_breg8:
+       case DW_OP_breg9:
+       case DW_OP_breg10:
+       case DW_OP_breg11:
+       case DW_OP_breg12:
+       case DW_OP_breg13:
+       case DW_OP_breg14:
+       case DW_OP_breg15:
+       case DW_OP_breg16:
+       case DW_OP_breg17:
+       case DW_OP_breg18:
+       case DW_OP_breg19:
+       case DW_OP_breg20:
+       case DW_OP_breg21:
+       case DW_OP_breg22:
+       case DW_OP_breg23:
+       case DW_OP_breg24:
+       case DW_OP_breg25:
+       case DW_OP_breg26:
+       case DW_OP_breg27:
+       case DW_OP_breg28:
+       case DW_OP_breg29:
+       case DW_OP_breg30:
+       case DW_OP_breg31:
+         offreg = 1;
+         basereg = op - DW_OP_breg0;
+         stack[++stacki] = read_signed_leb128 (NULL, (data + i), &bytes_read);
+         i += bytes_read;
+         break;
+
+       case DW_OP_bregx:
+         offreg = 1;
+         basereg = read_unsigned_leb128 (NULL, (data + i), &bytes_read);
+         i += bytes_read;
+         stack[++stacki] = read_signed_leb128 (NULL, (data + i), &bytes_read);
+         i += bytes_read;
+         break;
+
+       case DW_OP_fbreg:
+         stack[++stacki] = read_signed_leb128 (NULL, (data + i), &bytes_read);
+         i += bytes_read;
+         if (frame_base_reg >= 0)
+           {
+             offreg = 1;
+             basereg = frame_base_reg;
+             stack[stacki] += frame_base_offset;
+           }
+         else
+           {
+             complain (&dwarf2_missing_at_frame_base);
+             islocal = 1;
+           }
+         break;
+
+       case DW_OP_addr:
+         stack[++stacki] = read_address (objfile->obfd, &data[i],
+                                         cu_header, &bytes_read);
+         i += bytes_read;
+         break;
+
+       case DW_OP_const1u:
+         stack[++stacki] = read_1_byte (objfile->obfd, &data[i]);
+         i += 1;
+         break;
+
+       case DW_OP_const1s:
+         stack[++stacki] = read_1_signed_byte (objfile->obfd, &data[i]);
+         i += 1;
+         break;
+
+       case DW_OP_const2u:
+         stack[++stacki] = read_2_bytes (objfile->obfd, &data[i]);
+         i += 2;
+         break;
+
+       case DW_OP_const2s:
+         stack[++stacki] = read_2_signed_bytes (objfile->obfd, &data[i]);
+         i += 2;
+         break;
+
+       case DW_OP_const4u:
+         stack[++stacki] = read_4_bytes (objfile->obfd, &data[i]);
+         i += 4;
+         break;
+
+       case DW_OP_const4s:
+         stack[++stacki] = read_4_signed_bytes (objfile->obfd, &data[i]);
+         i += 4;
+         break;
+
+       case DW_OP_constu:
+         stack[++stacki] = read_unsigned_leb128 (NULL, (data + i),
+                                                 &bytes_read);
+         i += bytes_read;
+         break;
+
+       case DW_OP_consts:
+         stack[++stacki] = read_signed_leb128 (NULL, (data + i), &bytes_read);
+         i += bytes_read;
+         break;
+
+       case DW_OP_dup:
+         stack[stacki + 1] = stack[stacki];
+         stacki++;
+         break;
+
+       case DW_OP_plus:
+         stack[stacki - 1] += stack[stacki];
+         stacki--;
+         break;
+
+       case DW_OP_plus_uconst:
+         stack[stacki] += read_unsigned_leb128 (NULL, (data + i), &bytes_read);
+         i += bytes_read;
+         break;
+
+       case DW_OP_minus:
+         stack[stacki - 1] -= stack[stacki];
+         stacki--;
+         break;
+
+       case DW_OP_deref:
+         isderef = 1;
+         /* If we're not the last op, then we definitely can't encode
+            this using GDB's address_class enum.  */
+         if (i < size)
+           complain (&dwarf2_complex_location_expr);
+         break;
+
+       default:
+         complain (&dwarf2_unsupported_stack_op, dwarf_stack_op_name (op));
+         return (stack[stacki]);
+       }
+    }
+  return (stack[stacki]);
+}
+
+/* memory allocation interface */
+
+/* ARGSUSED */
+static void
+dwarf2_free_tmp_obstack (PTR ignore)
+{
+  obstack_free (&dwarf2_tmp_obstack, NULL);
+}
+
+static struct dwarf_block *
+dwarf_alloc_block (void)
+{
+  struct dwarf_block *blk;
+
+  blk = (struct dwarf_block *)
+    obstack_alloc (&dwarf2_tmp_obstack, sizeof (struct dwarf_block));
+  return (blk);
+}
+
+static struct abbrev_info *
+dwarf_alloc_abbrev (void)
+{
+  struct abbrev_info *abbrev;
+
+  abbrev = (struct abbrev_info *) xmalloc (sizeof (struct abbrev_info));
+  memset (abbrev, 0, sizeof (struct abbrev_info));
+  return (abbrev);
+}
+
+static struct die_info *
+dwarf_alloc_die (void)
+{
+  struct die_info *die;
+
+  die = (struct die_info *) xmalloc (sizeof (struct die_info));
+  memset (die, 0, sizeof (struct die_info));
+  return (die);
+}
+
+\f
+/* Macro support.  */
+
+
+/* Return the full name of file number I in *LH's file name table.
+   Use COMP_DIR as the name of the current directory of the
+   compilation.  The result is allocated using xmalloc; the caller is
+   responsible for freeing it.  */
+static char *
+file_full_name (int file, struct line_header *lh, const char *comp_dir)
+{
+  struct file_entry *fe = &lh->file_names[file - 1];
+  
+  if (IS_ABSOLUTE_PATH (fe->name))
+    return xstrdup (fe->name);
+  else
+    {
+      const char *dir;
+      int dir_len;
+      char *full_name;
+
+      if (fe->dir_index)
+        dir = lh->include_dirs[fe->dir_index - 1];
+      else
+        dir = comp_dir;
+
+      if (dir)
+        {
+          dir_len = strlen (dir);
+          full_name = xmalloc (dir_len + 1 + strlen (fe->name) + 1);
+          strcpy (full_name, dir);
+          full_name[dir_len] = '/';
+          strcpy (full_name + dir_len + 1, fe->name);
+          return full_name;
+        }
+      else
+        return xstrdup (fe->name);
+    }
+}
+
+
+static struct macro_source_file *
+macro_start_file (int file, int line,
+                  struct macro_source_file *current_file,
+                  const char *comp_dir,
+                  struct line_header *lh, struct objfile *objfile)
+{
+  /* The full name of this source file.  */
+  char *full_name = file_full_name (file, lh, comp_dir);
+
+  /* We don't create a macro table for this compilation unit
+     at all until we actually get a filename.  */
+  if (! pending_macros)
+    pending_macros = new_macro_table (&objfile->symbol_obstack,
+                                      objfile->macro_cache);
+
+  if (! current_file)
+    /* If we have no current file, then this must be the start_file
+       directive for the compilation unit's main source file.  */
+    current_file = macro_set_main (pending_macros, full_name);
+  else
+    current_file = macro_include (current_file, line, full_name);
+
+  xfree (full_name);
+              
+  return current_file;
+}
+
+
+/* Copy the LEN characters at BUF to a xmalloc'ed block of memory,
+   followed by a null byte.  */
+static char *
+copy_string (const char *buf, int len)
+{
+  char *s = xmalloc (len + 1);
+  memcpy (s, buf, len);
+  s[len] = '\0';
+
+  return s;
+}
+
+
+static const char *
+consume_improper_spaces (const char *p, const char *body)
+{
+  if (*p == ' ')
+    {
+      complain (&dwarf2_macro_spaces_in_definition, body);
+
+      while (*p == ' ')
+        p++;
+    }
+
+  return p;
+}
+
+
+static void
+parse_macro_definition (struct macro_source_file *file, int line,
+                        const char *body)
+{
+  const char *p;
+
+  /* The body string takes one of two forms.  For object-like macro
+     definitions, it should be:
+
+        <macro name> " " <definition>
+
+     For function-like macro definitions, it should be:
+
+        <macro name> "() " <definition>
+     or
+        <macro name> "(" <arg name> ( "," <arg name> ) * ") " <definition>
+
+     Spaces may appear only where explicitly indicated, and in the
+     <definition>.
+
+     The Dwarf 2 spec says that an object-like macro's name is always
+     followed by a space, but versions of GCC around March 2002 omit
+     the space when the macro's definition is the empty string. 
+
+     The Dwarf 2 spec says that there should be no spaces between the
+     formal arguments in a function-like macro's formal argument list,
+     but versions of GCC around March 2002 include spaces after the
+     commas.  */
+
+
+  /* Find the extent of the macro name.  The macro name is terminated
+     by either a space or null character (for an object-like macro) or
+     an opening paren (for a function-like macro).  */
+  for (p = body; *p; p++)
+    if (*p == ' ' || *p == '(')
+      break;
+
+  if (*p == ' ' || *p == '\0')
+    {
+      /* It's an object-like macro.  */
+      int name_len = p - body;
+      char *name = copy_string (body, name_len);
+      const char *replacement;
+
+      if (*p == ' ')
+        replacement = body + name_len + 1;
+      else
+        {
+          complain (&dwarf2_macro_malformed_definition, body);
+          replacement = body + name_len;
+        }
+      
+      macro_define_object (file, line, name, replacement);
+
+      xfree (name);
+    }
+  else if (*p == '(')
+    {
+      /* It's a function-like macro.  */
+      char *name = copy_string (body, p - body);
+      int argc = 0;
+      int argv_size = 1;
+      char **argv = xmalloc (argv_size * sizeof (*argv));
+
+      p++;
+
+      p = consume_improper_spaces (p, body);
+
+      /* Parse the formal argument list.  */
+      while (*p && *p != ')')
+        {
+          /* Find the extent of the current argument name.  */
+          const char *arg_start = p;
+
+          while (*p && *p != ',' && *p != ')' && *p != ' ')
+            p++;
+
+          if (! *p || p == arg_start)
+            complain (&dwarf2_macro_malformed_definition,
+                      body);
+          else
+            {
+              /* Make sure argv has room for the new argument.  */
+              if (argc >= argv_size)
+                {
+                  argv_size *= 2;
+                  argv = xrealloc (argv, argv_size * sizeof (*argv));
+                }
+
+              argv[argc++] = copy_string (arg_start, p - arg_start);
+            }
+
+          p = consume_improper_spaces (p, body);
+
+          /* Consume the comma, if present.  */
+          if (*p == ',')
+            {
+              p++;
+
+              p = consume_improper_spaces (p, body);
+            }
+        }
+
+      if (*p == ')')
+        {
+          p++;
+
+          if (*p == ' ')
+            /* Perfectly formed definition, no complaints.  */
+            macro_define_function (file, line, name,
+                                   argc, (const char **) argv, 
+                                   p + 1);
+          else if (*p == '\0')
+            {
+              /* Complain, but do define it.  */
+              complain (&dwarf2_macro_malformed_definition, body);
+              macro_define_function (file, line, name,
+                                     argc, (const char **) argv, 
+                                     p);
+            }
+          else
+            /* Just complain.  */
+            complain (&dwarf2_macro_malformed_definition, body);
+        }
+      else
+        /* Just complain.  */
+        complain (&dwarf2_macro_malformed_definition, body);
+
+      xfree (name);
+      {
+        int i;
+
+        for (i = 0; i < argc; i++)
+          xfree (argv[i]);
+      }
+      xfree (argv);
+    }
+  else
+    complain (&dwarf2_macro_malformed_definition, body);
+}
+
+
+static void
+dwarf_decode_macros (struct line_header *lh, unsigned int offset,
+                     char *comp_dir, bfd *abfd,
+                     const struct comp_unit_head *cu_header,
+                     struct objfile *objfile)
+{
+  char *mac_ptr, *mac_end;
+  struct macro_source_file *current_file = 0;
+
+  if (dwarf_macinfo_buffer == NULL)
+    {
+      complain (&dwarf2_missing_macinfo_section);
+      return;
+    }
+
+  mac_ptr = dwarf_macinfo_buffer + offset;
+  mac_end = dwarf_macinfo_buffer + dwarf_macinfo_size;
+
+  for (;;)
+    {
+      enum dwarf_macinfo_record_type macinfo_type;
+
+      /* Do we at least have room for a macinfo type byte?  */
+      if (mac_ptr >= mac_end)
+        {
+          complain (&dwarf2_macros_too_long);
+          return;
+        }
+
+      macinfo_type = read_1_byte (abfd, mac_ptr);
+      mac_ptr++;
+
+      switch (macinfo_type)
+        {
+          /* A zero macinfo type indicates the end of the macro
+             information.  */
+        case 0:
+          return;
+
+        case DW_MACINFO_define:
+        case DW_MACINFO_undef:
+          {
+            int bytes_read;
+            int line;
+            char *body;
+
+            line = read_unsigned_leb128 (abfd, mac_ptr, &bytes_read);
+            mac_ptr += bytes_read;
+            body = read_string (abfd, mac_ptr, &bytes_read);
+            mac_ptr += bytes_read;
+
+            if (! current_file)
+              complain (&dwarf2_macro_outside_file,
+                        macinfo_type == DW_MACINFO_define ? "definition" :
+                        macinfo_type == DW_MACINFO_undef ? "undefinition" :
+                        "something-or-other",
+                        body);
+            else
+              {
+                if (macinfo_type == DW_MACINFO_define)
+                  parse_macro_definition (current_file, line, body);
+                else if (macinfo_type == DW_MACINFO_undef)
+                  macro_undef (current_file, line, body);
+              }
+          }
+          break;
+
+        case DW_MACINFO_start_file:
+          {
+            int bytes_read;
+            int line, file;
+
+            line = read_unsigned_leb128 (abfd, mac_ptr, &bytes_read);
+            mac_ptr += bytes_read;
+            file = read_unsigned_leb128 (abfd, mac_ptr, &bytes_read);
+            mac_ptr += bytes_read;
+
+            current_file = macro_start_file (file, line,
+                                             current_file, comp_dir,
+                                             lh, objfile);
+          }
+          break;
+
+        case DW_MACINFO_end_file:
+          if (! current_file)
+            complain (&dwarf2_macro_unmatched_end_file);
+          else
+            {
+              current_file = current_file->included_by;
+              if (! current_file)
+                {
+                  enum dwarf_macinfo_record_type next_type;
+
+                  /* GCC circa March 2002 doesn't produce the zero
+                     type byte marking the end of the compilation
+                     unit.  Complain if it's not there, but exit no
+                     matter what.  */
+
+                  /* Do we at least have room for a macinfo type byte?  */
+                  if (mac_ptr >= mac_end)
+                    {
+                      complain (&dwarf2_macros_too_long);
+                      return;
+                    }
+
+                  /* We don't increment mac_ptr here, so this is just
+                     a look-ahead.  */
+                  next_type = read_1_byte (abfd, mac_ptr);
+                  if (next_type != 0)
+                    complain (&dwarf2_macros_not_terminated);
+
+                  return;
+                }
+            }
+          break;
+
+        case DW_MACINFO_vendor_ext:
+          {
+            int bytes_read;
+            int constant;
+            char *string;
+
+            constant = read_unsigned_leb128 (abfd, mac_ptr, &bytes_read);
+            mac_ptr += bytes_read;
+            string = read_string (abfd, mac_ptr, &bytes_read);
+            mac_ptr += bytes_read;
+
+            /* We don't recognize any vendor extensions.  */
+          }
+          break;
+        }
+    }
+}
+
+/* Check if the attribute's form is a DW_FORM_block*
+   if so return true else false. */
+static int
+attr_form_is_block (struct attribute *attr)
+{
+  return (attr == NULL ? 0 :
+      attr->form == DW_FORM_block1
+      || attr->form == DW_FORM_block2
+      || attr->form == DW_FORM_block4
+      || attr->form == DW_FORM_block);
+}
diff --git a/gdb/dwarfread.c b/gdb/dwarfread.c
new file mode 100644 (file)
index 0000000..9c4201d
--- /dev/null
@@ -0,0 +1,3788 @@
+/* DWARF debugging format support for GDB.
+   Copyright 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000,
+   2001, 2002
+   Free Software Foundation, Inc.
+   Written by Fred Fish at Cygnus Support.  Portions based on dbxread.c,
+   mipsread.c, coffread.c, and dwarfread.c from a Data General SVR4 gdb port.
+
+   This file is part of GDB.
+
+   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.  */
+
+/*
+
+   FIXME: Do we need to generate dependencies in partial symtabs?
+   (Perhaps we don't need to).
+
+   FIXME: Resolve minor differences between what information we put in the
+   partial symbol table and what dbxread puts in.  For example, we don't yet
+   put enum constants there.  And dbxread seems to invent a lot of typedefs
+   we never see.  Use the new printpsym command to see the partial symbol table
+   contents.
+
+   FIXME: Figure out a better way to tell gdb about the name of the function
+   contain the user's entry point (I.E. main())
+
+   FIXME: See other FIXME's and "ifdef 0" scattered throughout the code for
+   other things to work on, if you get bored. :-)
+
+ */
+
+#include "defs.h"
+#include "symtab.h"
+#include "gdbtypes.h"
+#include "symfile.h"
+#include "objfiles.h"
+#include "elf/dwarf.h"
+#include "buildsym.h"
+#include "demangle.h"
+#include "expression.h"                /* Needed for enum exp_opcode in language.h, sigh... */
+#include "language.h"
+#include "complaints.h"
+
+#include <fcntl.h>
+#include "gdb_string.h"
+
+/* Some macros to provide DIE info for complaints. */
+
+#define DIE_ID (curdie!=NULL ? curdie->die_ref : 0)
+#define DIE_NAME (curdie!=NULL && curdie->at_name!=NULL) ? curdie->at_name : ""
+
+/* Complaints that can be issued during DWARF debug info reading. */
+
+struct complaint no_bfd_get_N =
+{
+  "DIE @ 0x%x \"%s\", no bfd support for %d byte data object", 0, 0
+};
+
+struct complaint malformed_die =
+{
+  "DIE @ 0x%x \"%s\", malformed DIE, bad length (%d bytes)", 0, 0
+};
+
+struct complaint bad_die_ref =
+{
+  "DIE @ 0x%x \"%s\", reference to DIE (0x%x) outside compilation unit", 0, 0
+};
+
+struct complaint unknown_attribute_form =
+{
+  "DIE @ 0x%x \"%s\", unknown attribute form (0x%x)", 0, 0
+};
+
+struct complaint unknown_attribute_length =
+{
+  "DIE @ 0x%x \"%s\", unknown attribute length, skipped remaining attributes", 0, 0
+};
+
+struct complaint unexpected_fund_type =
+{
+  "DIE @ 0x%x \"%s\", unexpected fundamental type 0x%x", 0, 0
+};
+
+struct complaint unknown_type_modifier =
+{
+  "DIE @ 0x%x \"%s\", unknown type modifier %u", 0, 0
+};
+
+struct complaint volatile_ignored =
+{
+  "DIE @ 0x%x \"%s\", type modifier 'volatile' ignored", 0, 0
+};
+
+struct complaint const_ignored =
+{
+  "DIE @ 0x%x \"%s\", type modifier 'const' ignored", 0, 0
+};
+
+struct complaint botched_modified_type =
+{
+  "DIE @ 0x%x \"%s\", botched modified type decoding (mtype 0x%x)", 0, 0
+};
+
+struct complaint op_deref2 =
+{
+  "DIE @ 0x%x \"%s\", OP_DEREF2 address 0x%x not handled", 0, 0
+};
+
+struct complaint op_deref4 =
+{
+  "DIE @ 0x%x \"%s\", OP_DEREF4 address 0x%x not handled", 0, 0
+};
+
+struct complaint basereg_not_handled =
+{
+  "DIE @ 0x%x \"%s\", BASEREG %d not handled", 0, 0
+};
+
+struct complaint dup_user_type_allocation =
+{
+  "DIE @ 0x%x \"%s\", internal error: duplicate user type allocation", 0, 0
+};
+
+struct complaint dup_user_type_definition =
+{
+  "DIE @ 0x%x \"%s\", internal error: duplicate user type definition", 0, 0
+};
+
+struct complaint missing_tag =
+{
+  "DIE @ 0x%x \"%s\", missing class, structure, or union tag", 0, 0
+};
+
+struct complaint bad_array_element_type =
+{
+  "DIE @ 0x%x \"%s\", bad array element type attribute 0x%x", 0, 0
+};
+
+struct complaint subscript_data_items =
+{
+  "DIE @ 0x%x \"%s\", can't decode subscript data items", 0, 0
+};
+
+struct complaint unhandled_array_subscript_format =
+{
+  "DIE @ 0x%x \"%s\", array subscript format 0x%x not handled yet", 0, 0
+};
+
+struct complaint unknown_array_subscript_format =
+{
+  "DIE @ 0x%x \"%s\", unknown array subscript format %x", 0, 0
+};
+
+struct complaint not_row_major =
+{
+  "DIE @ 0x%x \"%s\", array not row major; not handled correctly", 0, 0
+};
+
+struct complaint missing_at_name =
+{
+  "DIE @ 0x%x, AT_name tag missing", 0, 0
+};
+
+typedef unsigned int DIE_REF;  /* Reference to a DIE */
+
+#ifndef GCC_PRODUCER
+#define GCC_PRODUCER "GNU C "
+#endif
+
+#ifndef GPLUS_PRODUCER
+#define GPLUS_PRODUCER "GNU C++ "
+#endif
+
+#ifndef LCC_PRODUCER
+#define LCC_PRODUCER "NCR C/C++"
+#endif
+
+/* OBSOLETE #ifndef CHILL_PRODUCER */
+/* OBSOLETE #define CHILL_PRODUCER "GNU Chill " */
+/* OBSOLETE #endif */
+
+/* Flags to target_to_host() that tell whether or not the data object is
+   expected to be signed.  Used, for example, when fetching a signed
+   integer in the target environment which is used as a signed integer
+   in the host environment, and the two environments have different sized
+   ints.  In this case, *somebody* has to sign extend the smaller sized
+   int. */
+
+#define GET_UNSIGNED   0       /* No sign extension required */
+#define GET_SIGNED     1       /* Sign extension required */
+
+/* Defines for things which are specified in the document "DWARF Debugging
+   Information Format" published by UNIX International, Programming Languages
+   SIG.  These defines are based on revision 1.0.0, Jan 20, 1992. */
+
+#define SIZEOF_DIE_LENGTH      4
+#define SIZEOF_DIE_TAG         2
+#define SIZEOF_ATTRIBUTE       2
+#define SIZEOF_FORMAT_SPECIFIER        1
+#define SIZEOF_FMT_FT          2
+#define SIZEOF_LINETBL_LENGTH  4
+#define SIZEOF_LINETBL_LINENO  4
+#define SIZEOF_LINETBL_STMT    2
+#define SIZEOF_LINETBL_DELTA   4
+#define SIZEOF_LOC_ATOM_CODE   1
+
+#define FORM_FROM_ATTR(attr)   ((attr) & 0xF)  /* Implicitly specified */
+
+/* Macros that return the sizes of various types of data in the target
+   environment.
+
+   FIXME:  Currently these are just compile time constants (as they are in
+   other parts of gdb as well).  They need to be able to get the right size
+   either from the bfd or possibly from the DWARF info.  It would be nice if
+   the DWARF producer inserted DIES that describe the fundamental types in
+   the target environment into the DWARF info, similar to the way dbx stabs
+   producers produce information about their fundamental types. */
+
+#define TARGET_FT_POINTER_SIZE(objfile)        (TARGET_PTR_BIT / TARGET_CHAR_BIT)
+#define TARGET_FT_LONG_SIZE(objfile)   (TARGET_LONG_BIT / TARGET_CHAR_BIT)
+
+/* The Amiga SVR4 header file <dwarf.h> defines AT_element_list as a
+   FORM_BLOCK2, and this is the value emitted by the AT&T compiler.
+   However, the Issue 2 DWARF specification from AT&T defines it as
+   a FORM_BLOCK4, as does the latest specification from UI/PLSIG.
+   For backwards compatibility with the AT&T compiler produced executables
+   we define AT_short_element_list for this variant. */
+
+#define        AT_short_element_list    (0x00f0|FORM_BLOCK2)
+
+/* The DWARF debugging information consists of two major pieces,
+   one is a block of DWARF Information Entries (DIE's) and the other
+   is a line number table.  The "struct dieinfo" structure contains
+   the information for a single DIE, the one currently being processed.
+
+   In order to make it easier to randomly access the attribute fields
+   of the current DIE, which are specifically unordered within the DIE,
+   each DIE is scanned and an instance of the "struct dieinfo"
+   structure is initialized.
+
+   Initialization is done in two levels.  The first, done by basicdieinfo(),
+   just initializes those fields that are vital to deciding whether or not
+   to use this DIE, how to skip past it, etc.  The second, done by the
+   function completedieinfo(), fills in the rest of the information.
+
+   Attributes which have block forms are not interpreted at the time
+   the DIE is scanned, instead we just save pointers to the start
+   of their value fields.
+
+   Some fields have a flag <name>_p that is set when the value of the
+   field is valid (I.E. we found a matching attribute in the DIE).  Since
+   we may want to test for the presence of some attributes in the DIE,
+   such as AT_low_pc, without restricting the values of the field,
+   we need someway to note that we found such an attribute.
+
+ */
+
+typedef char BLOCK;
+
+struct dieinfo
+  {
+    char *die;                 /* Pointer to the raw DIE data */
+    unsigned long die_length;  /* Length of the raw DIE data */
+    DIE_REF die_ref;           /* Offset of this DIE */
+    unsigned short die_tag;    /* Tag for this DIE */
+    unsigned long at_padding;
+    unsigned long at_sibling;
+    BLOCK *at_location;
+    char *at_name;
+    unsigned short at_fund_type;
+    BLOCK *at_mod_fund_type;
+    unsigned long at_user_def_type;
+    BLOCK *at_mod_u_d_type;
+    unsigned short at_ordering;
+    BLOCK *at_subscr_data;
+    unsigned long at_byte_size;
+    unsigned short at_bit_offset;
+    unsigned long at_bit_size;
+    BLOCK *at_element_list;
+    unsigned long at_stmt_list;
+    CORE_ADDR at_low_pc;
+    CORE_ADDR at_high_pc;
+    unsigned long at_language;
+    unsigned long at_member;
+    unsigned long at_discr;
+    BLOCK *at_discr_value;
+    BLOCK *at_string_length;
+    char *at_comp_dir;
+    char *at_producer;
+    unsigned long at_start_scope;
+    unsigned long at_stride_size;
+    unsigned long at_src_info;
+    char *at_prototyped;
+    unsigned int has_at_low_pc:1;
+    unsigned int has_at_stmt_list:1;
+    unsigned int has_at_byte_size:1;
+    unsigned int short_element_list:1;
+
+    /* Kludge to identify register variables */
+
+    unsigned int isreg;
+
+    /* Kludge to identify optimized out variables */
+
+    unsigned int optimized_out;
+
+    /* Kludge to identify basereg references.
+       Nonzero if we have an offset relative to a basereg.  */
+
+    unsigned int offreg;
+
+    /* Kludge to identify which base register is it relative to.  */
+
+    unsigned int basereg;
+  };
+
+static int diecount;           /* Approximate count of dies for compilation unit */
+static struct dieinfo *curdie; /* For warnings and such */
+
+static char *dbbase;           /* Base pointer to dwarf info */
+static int dbsize;             /* Size of dwarf info in bytes */
+static int dbroff;             /* Relative offset from start of .debug section */
+static char *lnbase;           /* Base pointer to line section */
+
+/* This value is added to each symbol value.  FIXME:  Generalize to 
+   the section_offsets structure used by dbxread (once this is done,
+   pass the appropriate section number to end_symtab).  */
+static CORE_ADDR baseaddr;     /* Add to each symbol value */
+
+/* The section offsets used in the current psymtab or symtab.  FIXME,
+   only used to pass one value (baseaddr) at the moment.  */
+static struct section_offsets *base_section_offsets;
+
+/* We put a pointer to this structure in the read_symtab_private field
+   of the psymtab.  */
+
+struct dwfinfo
+  {
+    /* Always the absolute file offset to the start of the ".debug"
+       section for the file containing the DIE's being accessed.  */
+    file_ptr dbfoff;
+    /* Relative offset from the start of the ".debug" section to the
+       first DIE to be accessed.  When building the partial symbol
+       table, this value will be zero since we are accessing the
+       entire ".debug" section.  When expanding a partial symbol
+       table entry, this value will be the offset to the first
+       DIE for the compilation unit containing the symbol that
+       triggers the expansion.  */
+    int dbroff;
+    /* The size of the chunk of DIE's being examined, in bytes.  */
+    int dblength;
+    /* The absolute file offset to the line table fragment.  Ignored
+       when building partial symbol tables, but used when expanding
+       them, and contains the absolute file offset to the fragment
+       of the ".line" section containing the line numbers for the
+       current compilation unit.  */
+    file_ptr lnfoff;
+  };
+
+#define DBFOFF(p) (((struct dwfinfo *)((p)->read_symtab_private))->dbfoff)
+#define DBROFF(p) (((struct dwfinfo *)((p)->read_symtab_private))->dbroff)
+#define DBLENGTH(p) (((struct dwfinfo *)((p)->read_symtab_private))->dblength)
+#define LNFOFF(p) (((struct dwfinfo *)((p)->read_symtab_private))->lnfoff)
+
+/* The generic symbol table building routines have separate lists for
+   file scope symbols and all all other scopes (local scopes).  So
+   we need to select the right one to pass to add_symbol_to_list().
+   We do it by keeping a pointer to the correct list in list_in_scope.
+
+   FIXME:  The original dwarf code just treated the file scope as the first
+   local scope, and all other local scopes as nested local scopes, and worked
+   fine.  Check to see if we really need to distinguish these in buildsym.c */
+
+struct pending **list_in_scope = &file_symbols;
+
+/* DIES which have user defined types or modified user defined types refer to
+   other DIES for the type information.  Thus we need to associate the offset
+   of a DIE for a user defined type with a pointer to the type information.
+
+   Originally this was done using a simple but expensive algorithm, with an
+   array of unsorted structures, each containing an offset/type-pointer pair.
+   This array was scanned linearly each time a lookup was done.  The result
+   was that gdb was spending over half it's startup time munging through this
+   array of pointers looking for a structure that had the right offset member.
+
+   The second attempt used the same array of structures, but the array was
+   sorted using qsort each time a new offset/type was recorded, and a binary
+   search was used to find the type pointer for a given DIE offset.  This was
+   even slower, due to the overhead of sorting the array each time a new
+   offset/type pair was entered.
+
+   The third attempt uses a fixed size array of type pointers, indexed by a
+   value derived from the DIE offset.  Since the minimum DIE size is 4 bytes,
+   we can divide any DIE offset by 4 to obtain a unique index into this fixed
+   size array.  Since each element is a 4 byte pointer, it takes exactly as
+   much memory to hold this array as to hold the DWARF info for a given
+   compilation unit.  But it gets freed as soon as we are done with it.
+   This has worked well in practice, as a reasonable tradeoff between memory
+   consumption and speed, without having to resort to much more complicated
+   algorithms. */
+
+static struct type **utypes;   /* Pointer to array of user type pointers */
+static int numutypes;          /* Max number of user type pointers */
+
+/* Maintain an array of referenced fundamental types for the current
+   compilation unit being read.  For DWARF version 1, we have to construct
+   the fundamental types on the fly, since no information about the
+   fundamental types is supplied.  Each such fundamental type is created by
+   calling a language dependent routine to create the type, and then a
+   pointer to that type is then placed in the array at the index specified
+   by it's FT_<TYPENAME> value.  The array has a fixed size set by the
+   FT_NUM_MEMBERS compile time constant, which is the number of predefined
+   fundamental types gdb knows how to construct. */
+
+static struct type *ftypes[FT_NUM_MEMBERS];    /* Fundamental types */
+
+/* Record the language for the compilation unit which is currently being
+   processed.  We know it once we have seen the TAG_compile_unit DIE,
+   and we need it while processing the DIE's for that compilation unit.
+   It is eventually saved in the symtab structure, but we don't finalize
+   the symtab struct until we have processed all the DIE's for the
+   compilation unit.  We also need to get and save a pointer to the 
+   language struct for this language, so we can call the language
+   dependent routines for doing things such as creating fundamental
+   types. */
+
+static enum language cu_language;
+static const struct language_defn *cu_language_defn;
+
+/* Forward declarations of static functions so we don't have to worry
+   about ordering within this file.  */
+
+static void free_utypes (PTR);
+
+static int attribute_size (unsigned int);
+
+static CORE_ADDR target_to_host (char *, int, int, struct objfile *);
+
+static void add_enum_psymbol (struct dieinfo *, struct objfile *);
+
+static void handle_producer (char *);
+
+static void
+read_file_scope (struct dieinfo *, char *, char *, struct objfile *);
+
+static void
+read_func_scope (struct dieinfo *, char *, char *, struct objfile *);
+
+static void
+read_lexical_block_scope (struct dieinfo *, char *, char *, struct objfile *);
+
+static void scan_partial_symbols (char *, char *, struct objfile *);
+
+static void
+scan_compilation_units (char *, char *, file_ptr, file_ptr, struct objfile *);
+
+static void add_partial_symbol (struct dieinfo *, struct objfile *);
+
+static void basicdieinfo (struct dieinfo *, char *, struct objfile *);
+
+static void completedieinfo (struct dieinfo *, struct objfile *);
+
+static void dwarf_psymtab_to_symtab (struct partial_symtab *);
+
+static void psymtab_to_symtab_1 (struct partial_symtab *);
+
+static void read_ofile_symtab (struct partial_symtab *);
+
+static void process_dies (char *, char *, struct objfile *);
+
+static void
+read_structure_scope (struct dieinfo *, char *, char *, struct objfile *);
+
+static struct type *decode_array_element_type (char *);
+
+static struct type *decode_subscript_data_item (char *, char *);
+
+static void dwarf_read_array_type (struct dieinfo *);
+
+static void read_tag_pointer_type (struct dieinfo *dip);
+
+static void read_tag_string_type (struct dieinfo *dip);
+
+static void read_subroutine_type (struct dieinfo *, char *, char *);
+
+static void
+read_enumeration (struct dieinfo *, char *, char *, struct objfile *);
+
+static struct type *struct_type (struct dieinfo *, char *, char *,
+                                struct objfile *);
+
+static struct type *enum_type (struct dieinfo *, struct objfile *);
+
+static void decode_line_numbers (char *);
+
+static struct type *decode_die_type (struct dieinfo *);
+
+static struct type *decode_mod_fund_type (char *);
+
+static struct type *decode_mod_u_d_type (char *);
+
+static struct type *decode_modified_type (char *, unsigned int, int);
+
+static struct type *decode_fund_type (unsigned int);
+
+static char *create_name (char *, struct obstack *);
+
+static struct type *lookup_utype (DIE_REF);
+
+static struct type *alloc_utype (DIE_REF, struct type *);
+
+static struct symbol *new_symbol (struct dieinfo *, struct objfile *);
+
+static void
+synthesize_typedef (struct dieinfo *, struct objfile *, struct type *);
+
+static int locval (struct dieinfo *);
+
+static void set_cu_language (struct dieinfo *);
+
+static struct type *dwarf_fundamental_type (struct objfile *, int);
+
+
+/*
+
+   LOCAL FUNCTION
+
+   dwarf_fundamental_type -- lookup or create a fundamental type
+
+   SYNOPSIS
+
+   struct type *
+   dwarf_fundamental_type (struct objfile *objfile, int typeid)
+
+   DESCRIPTION
+
+   DWARF version 1 doesn't supply any fundamental type information,
+   so gdb has to construct such types.  It has a fixed number of
+   fundamental types that it knows how to construct, which is the
+   union of all types that it knows how to construct for all languages
+   that it knows about.  These are enumerated in gdbtypes.h.
+
+   As an example, assume we find a DIE that references a DWARF
+   fundamental type of FT_integer.  We first look in the ftypes
+   array to see if we already have such a type, indexed by the
+   gdb internal value of FT_INTEGER.  If so, we simply return a
+   pointer to that type.  If not, then we ask an appropriate
+   language dependent routine to create a type FT_INTEGER, using
+   defaults reasonable for the current target machine, and install
+   that type in ftypes for future reference.
+
+   RETURNS
+
+   Pointer to a fundamental type.
+
+ */
+
+static struct type *
+dwarf_fundamental_type (struct objfile *objfile, int typeid)
+{
+  if (typeid < 0 || typeid >= FT_NUM_MEMBERS)
+    {
+      error ("internal error - invalid fundamental type id %d", typeid);
+    }
+
+  /* Look for this particular type in the fundamental type vector.  If one is
+     not found, create and install one appropriate for the current language
+     and the current target machine. */
+
+  if (ftypes[typeid] == NULL)
+    {
+      ftypes[typeid] = cu_language_defn->la_fund_type (objfile, typeid);
+    }
+
+  return (ftypes[typeid]);
+}
+
+/*
+
+   LOCAL FUNCTION
+
+   set_cu_language -- set local copy of language for compilation unit
+
+   SYNOPSIS
+
+   void
+   set_cu_language (struct dieinfo *dip)
+
+   DESCRIPTION
+
+   Decode the language attribute for a compilation unit DIE and
+   remember what the language was.  We use this at various times
+   when processing DIE's for a given compilation unit.
+
+   RETURNS
+
+   No return value.
+
+ */
+
+static void
+set_cu_language (struct dieinfo *dip)
+{
+  switch (dip->at_language)
+    {
+    case LANG_C89:
+    case LANG_C:
+      cu_language = language_c;
+      break;
+    case LANG_C_PLUS_PLUS:
+      cu_language = language_cplus;
+      break;
+      /* OBSOLETE case LANG_CHILL: */
+      /* OBSOLETE   cu_language = language_chill; */
+      /* OBSOLETE   break; */
+    case LANG_MODULA2:
+      cu_language = language_m2;
+      break;
+    case LANG_FORTRAN77:
+    case LANG_FORTRAN90:
+      cu_language = language_fortran;
+      break;
+    case LANG_ADA83:
+    case LANG_COBOL74:
+    case LANG_COBOL85:
+    case LANG_PASCAL83:
+      /* We don't know anything special about these yet. */
+      cu_language = language_unknown;
+      break;
+    default:
+      /* If no at_language, try to deduce one from the filename */
+      cu_language = deduce_language_from_filename (dip->at_name);
+      break;
+    }
+  cu_language_defn = language_def (cu_language);
+}
+
+/*
+
+   GLOBAL FUNCTION
+
+   dwarf_build_psymtabs -- build partial symtabs from DWARF debug info
+
+   SYNOPSIS
+
+   void dwarf_build_psymtabs (struct objfile *objfile,
+   int mainline, file_ptr dbfoff, unsigned int dbfsize,
+   file_ptr lnoffset, unsigned int lnsize)
+
+   DESCRIPTION
+
+   This function is called upon to build partial symtabs from files
+   containing DIE's (Dwarf Information Entries) and DWARF line numbers.
+
+   It is passed a bfd* containing the DIES
+   and line number information, the corresponding filename for that
+   file, a base address for relocating the symbols, a flag indicating
+   whether or not this debugging information is from a "main symbol
+   table" rather than a shared library or dynamically linked file,
+   and file offset/size pairs for the DIE information and line number
+   information.
+
+   RETURNS
+
+   No return value.
+
+ */
+
+void
+dwarf_build_psymtabs (struct objfile *objfile, int mainline, file_ptr dbfoff,
+                     unsigned int dbfsize, file_ptr lnoffset,
+                     unsigned int lnsize)
+{
+  bfd *abfd = objfile->obfd;
+  struct cleanup *back_to;
+
+  current_objfile = objfile;
+  dbsize = dbfsize;
+  dbbase = xmalloc (dbsize);
+  dbroff = 0;
+  if ((bfd_seek (abfd, dbfoff, SEEK_SET) != 0) ||
+      (bfd_bread (dbbase, dbsize, abfd) != dbsize))
+    {
+      xfree (dbbase);
+      error ("can't read DWARF data from '%s'", bfd_get_filename (abfd));
+    }
+  back_to = make_cleanup (xfree, dbbase);
+
+  /* If we are reinitializing, or if we have never loaded syms yet, init.
+     Since we have no idea how many DIES we are looking at, we just guess
+     some arbitrary value. */
+
+  if (mainline
+      || (objfile->global_psymbols.size == 0
+         && objfile->static_psymbols.size == 0))
+    {
+      init_psymbol_list (objfile, 1024);
+    }
+
+  /* Save the relocation factor where everybody can see it.  */
+
+  base_section_offsets = objfile->section_offsets;
+  baseaddr = ANOFFSET (objfile->section_offsets, 0);
+
+  /* Follow the compilation unit sibling chain, building a partial symbol
+     table entry for each one.  Save enough information about each compilation
+     unit to locate the full DWARF information later. */
+
+  scan_compilation_units (dbbase, dbbase + dbsize, dbfoff, lnoffset, objfile);
+
+  do_cleanups (back_to);
+  current_objfile = NULL;
+}
+
+/*
+
+   LOCAL FUNCTION
+
+   read_lexical_block_scope -- process all dies in a lexical block
+
+   SYNOPSIS
+
+   static void read_lexical_block_scope (struct dieinfo *dip,
+   char *thisdie, char *enddie)
+
+   DESCRIPTION
+
+   Process all the DIES contained within a lexical block scope.
+   Start a new scope, process the dies, and then close the scope.
+
+ */
+
+static void
+read_lexical_block_scope (struct dieinfo *dip, char *thisdie, char *enddie,
+                         struct objfile *objfile)
+{
+  register struct context_stack *new;
+
+  push_context (0, dip->at_low_pc);
+  process_dies (thisdie + dip->die_length, enddie, objfile);
+  new = pop_context ();
+  if (local_symbols != NULL)
+    {
+      finish_block (0, &local_symbols, new->old_blocks, new->start_addr,
+                   dip->at_high_pc, objfile);
+    }
+  local_symbols = new->locals;
+}
+
+/*
+
+   LOCAL FUNCTION
+
+   lookup_utype -- look up a user defined type from die reference
+
+   SYNOPSIS
+
+   static type *lookup_utype (DIE_REF die_ref)
+
+   DESCRIPTION
+
+   Given a DIE reference, lookup the user defined type associated with
+   that DIE, if it has been registered already.  If not registered, then
+   return NULL.  Alloc_utype() can be called to register an empty
+   type for this reference, which will be filled in later when the
+   actual referenced DIE is processed.
+ */
+
+static struct type *
+lookup_utype (DIE_REF die_ref)
+{
+  struct type *type = NULL;
+  int utypeidx;
+
+  utypeidx = (die_ref - dbroff) / 4;
+  if ((utypeidx < 0) || (utypeidx >= numutypes))
+    {
+      complain (&bad_die_ref, DIE_ID, DIE_NAME);
+    }
+  else
+    {
+      type = *(utypes + utypeidx);
+    }
+  return (type);
+}
+
+
+/*
+
+   LOCAL FUNCTION
+
+   alloc_utype  -- add a user defined type for die reference
+
+   SYNOPSIS
+
+   static type *alloc_utype (DIE_REF die_ref, struct type *utypep)
+
+   DESCRIPTION
+
+   Given a die reference DIE_REF, and a possible pointer to a user
+   defined type UTYPEP, register that this reference has a user
+   defined type and either use the specified type in UTYPEP or
+   make a new empty type that will be filled in later.
+
+   We should only be called after calling lookup_utype() to verify that
+   there is not currently a type registered for DIE_REF.
+ */
+
+static struct type *
+alloc_utype (DIE_REF die_ref, struct type *utypep)
+{
+  struct type **typep;
+  int utypeidx;
+
+  utypeidx = (die_ref - dbroff) / 4;
+  typep = utypes + utypeidx;
+  if ((utypeidx < 0) || (utypeidx >= numutypes))
+    {
+      utypep = dwarf_fundamental_type (current_objfile, FT_INTEGER);
+      complain (&bad_die_ref, DIE_ID, DIE_NAME);
+    }
+  else if (*typep != NULL)
+    {
+      utypep = *typep;
+      complain (&dup_user_type_allocation, DIE_ID, DIE_NAME);
+    }
+  else
+    {
+      if (utypep == NULL)
+       {
+         utypep = alloc_type (current_objfile);
+       }
+      *typep = utypep;
+    }
+  return (utypep);
+}
+
+/*
+
+   LOCAL FUNCTION
+
+   free_utypes -- free the utypes array and reset pointer & count
+
+   SYNOPSIS
+
+   static void free_utypes (PTR dummy)
+
+   DESCRIPTION
+
+   Called via do_cleanups to free the utypes array, reset the pointer to NULL,
+   and set numutypes back to zero.  This ensures that the utypes does not get
+   referenced after being freed.
+ */
+
+static void
+free_utypes (PTR dummy)
+{
+  xfree (utypes);
+  utypes = NULL;
+  numutypes = 0;
+}
+
+
+/*
+
+   LOCAL FUNCTION
+
+   decode_die_type -- return a type for a specified die
+
+   SYNOPSIS
+
+   static struct type *decode_die_type (struct dieinfo *dip)
+
+   DESCRIPTION
+
+   Given a pointer to a die information structure DIP, decode the
+   type of the die and return a pointer to the decoded type.  All
+   dies without specific types default to type int.
+ */
+
+static struct type *
+decode_die_type (struct dieinfo *dip)
+{
+  struct type *type = NULL;
+
+  if (dip->at_fund_type != 0)
+    {
+      type = decode_fund_type (dip->at_fund_type);
+    }
+  else if (dip->at_mod_fund_type != NULL)
+    {
+      type = decode_mod_fund_type (dip->at_mod_fund_type);
+    }
+  else if (dip->at_user_def_type)
+    {
+      if ((type = lookup_utype (dip->at_user_def_type)) == NULL)
+       {
+         type = alloc_utype (dip->at_user_def_type, NULL);
+       }
+    }
+  else if (dip->at_mod_u_d_type)
+    {
+      type = decode_mod_u_d_type (dip->at_mod_u_d_type);
+    }
+  else
+    {
+      type = dwarf_fundamental_type (current_objfile, FT_VOID);
+    }
+  return (type);
+}
+
+/*
+
+   LOCAL FUNCTION
+
+   struct_type -- compute and return the type for a struct or union
+
+   SYNOPSIS
+
+   static struct type *struct_type (struct dieinfo *dip, char *thisdie,
+   char *enddie, struct objfile *objfile)
+
+   DESCRIPTION
+
+   Given pointer to a die information structure for a die which
+   defines a union or structure (and MUST define one or the other),
+   and pointers to the raw die data that define the range of dies which
+   define the members, compute and return the user defined type for the
+   structure or union.
+ */
+
+static struct type *
+struct_type (struct dieinfo *dip, char *thisdie, char *enddie,
+            struct objfile *objfile)
+{
+  struct type *type;
+  struct nextfield
+    {
+      struct nextfield *next;
+      struct field field;
+    };
+  struct nextfield *list = NULL;
+  struct nextfield *new;
+  int nfields = 0;
+  int n;
+  struct dieinfo mbr;
+  char *nextdie;
+  int anonymous_size;
+
+  if ((type = lookup_utype (dip->die_ref)) == NULL)
+    {
+      /* No forward references created an empty type, so install one now */
+      type = alloc_utype (dip->die_ref, NULL);
+    }
+  INIT_CPLUS_SPECIFIC (type);
+  switch (dip->die_tag)
+    {
+    case TAG_class_type:
+      TYPE_CODE (type) = TYPE_CODE_CLASS;
+      break;
+    case TAG_structure_type:
+      TYPE_CODE (type) = TYPE_CODE_STRUCT;
+      break;
+    case TAG_union_type:
+      TYPE_CODE (type) = TYPE_CODE_UNION;
+      break;
+    default:
+      /* Should never happen */
+      TYPE_CODE (type) = TYPE_CODE_UNDEF;
+      complain (&missing_tag, DIE_ID, DIE_NAME);
+      break;
+    }
+  /* Some compilers try to be helpful by inventing "fake" names for
+     anonymous enums, structures, and unions, like "~0fake" or ".0fake".
+     Thanks, but no thanks... */
+  if (dip->at_name != NULL
+      && *dip->at_name != '~'
+      && *dip->at_name != '.')
+    {
+      TYPE_TAG_NAME (type) = obconcat (&objfile->type_obstack,
+                                      "", "", dip->at_name);
+    }
+  /* Use whatever size is known.  Zero is a valid size.  We might however
+     wish to check has_at_byte_size to make sure that some byte size was
+     given explicitly, but DWARF doesn't specify that explicit sizes of
+     zero have to present, so complaining about missing sizes should 
+     probably not be the default. */
+  TYPE_LENGTH (type) = dip->at_byte_size;
+  thisdie += dip->die_length;
+  while (thisdie < enddie)
+    {
+      basicdieinfo (&mbr, thisdie, objfile);
+      completedieinfo (&mbr, objfile);
+      if (mbr.die_length <= SIZEOF_DIE_LENGTH)
+       {
+         break;
+       }
+      else if (mbr.at_sibling != 0)
+       {
+         nextdie = dbbase + mbr.at_sibling - dbroff;
+       }
+      else
+       {
+         nextdie = thisdie + mbr.die_length;
+       }
+      switch (mbr.die_tag)
+       {
+       case TAG_member:
+         /* Get space to record the next field's data.  */
+         new = (struct nextfield *) alloca (sizeof (struct nextfield));
+         new->next = list;
+         list = new;
+         /* Save the data.  */
+         list->field.name =
+           obsavestring (mbr.at_name, strlen (mbr.at_name),
+                         &objfile->type_obstack);
+         FIELD_TYPE (list->field) = decode_die_type (&mbr);
+         FIELD_BITPOS (list->field) = 8 * locval (&mbr);
+         /* Handle bit fields. */
+         FIELD_BITSIZE (list->field) = mbr.at_bit_size;
+         if (BITS_BIG_ENDIAN)
+           {
+             /* For big endian bits, the at_bit_offset gives the
+                additional bit offset from the MSB of the containing
+                anonymous object to the MSB of the field.  We don't
+                have to do anything special since we don't need to
+                know the size of the anonymous object. */
+             FIELD_BITPOS (list->field) += mbr.at_bit_offset;
+           }
+         else
+           {
+             /* For little endian bits, we need to have a non-zero
+                at_bit_size, so that we know we are in fact dealing
+                with a bitfield.  Compute the bit offset to the MSB
+                of the anonymous object, subtract off the number of
+                bits from the MSB of the field to the MSB of the
+                object, and then subtract off the number of bits of
+                the field itself.  The result is the bit offset of
+                the LSB of the field. */
+             if (mbr.at_bit_size > 0)
+               {
+                 if (mbr.has_at_byte_size)
+                   {
+                     /* The size of the anonymous object containing
+                        the bit field is explicit, so use the
+                        indicated size (in bytes). */
+                     anonymous_size = mbr.at_byte_size;
+                   }
+                 else
+                   {
+                     /* The size of the anonymous object containing
+                        the bit field matches the size of an object
+                        of the bit field's type.  DWARF allows
+                        at_byte_size to be left out in such cases, as
+                        a debug information size optimization. */
+                     anonymous_size = TYPE_LENGTH (list->field.type);
+                   }
+                 FIELD_BITPOS (list->field) +=
+                   anonymous_size * 8 - mbr.at_bit_offset - mbr.at_bit_size;
+               }
+           }
+         nfields++;
+         break;
+       default:
+         process_dies (thisdie, nextdie, objfile);
+         break;
+       }
+      thisdie = nextdie;
+    }
+  /* Now create the vector of fields, and record how big it is.  We may
+     not even have any fields, if this DIE was generated due to a reference
+     to an anonymous structure or union.  In this case, TYPE_FLAG_STUB is
+     set, which clues gdb in to the fact that it needs to search elsewhere
+     for the full structure definition. */
+  if (nfields == 0)
+    {
+      TYPE_FLAGS (type) |= TYPE_FLAG_STUB;
+    }
+  else
+    {
+      TYPE_NFIELDS (type) = nfields;
+      TYPE_FIELDS (type) = (struct field *)
+       TYPE_ALLOC (type, sizeof (struct field) * nfields);
+      /* Copy the saved-up fields into the field vector.  */
+      for (n = nfields; list; list = list->next)
+       {
+         TYPE_FIELD (type, --n) = list->field;
+       }
+    }
+  return (type);
+}
+
+/*
+
+   LOCAL FUNCTION
+
+   read_structure_scope -- process all dies within struct or union
+
+   SYNOPSIS
+
+   static void read_structure_scope (struct dieinfo *dip,
+   char *thisdie, char *enddie, struct objfile *objfile)
+
+   DESCRIPTION
+
+   Called when we find the DIE that starts a structure or union
+   scope (definition) to process all dies that define the members
+   of the structure or union.  DIP is a pointer to the die info
+   struct for the DIE that names the structure or union.
+
+   NOTES
+
+   Note that we need to call struct_type regardless of whether or not
+   the DIE has an at_name attribute, since it might be an anonymous
+   structure or union.  This gets the type entered into our set of
+   user defined types.
+
+   However, if the structure is incomplete (an opaque struct/union)
+   then suppress creating a symbol table entry for it since gdb only
+   wants to find the one with the complete definition.  Note that if
+   it is complete, we just call new_symbol, which does it's own
+   checking about whether the struct/union is anonymous or not (and
+   suppresses creating a symbol table entry itself).
+
+ */
+
+static void
+read_structure_scope (struct dieinfo *dip, char *thisdie, char *enddie,
+                     struct objfile *objfile)
+{
+  struct type *type;
+  struct symbol *sym;
+
+  type = struct_type (dip, thisdie, enddie, objfile);
+  if (!TYPE_STUB (type))
+    {
+      sym = new_symbol (dip, objfile);
+      if (sym != NULL)
+       {
+         SYMBOL_TYPE (sym) = type;
+         if (cu_language == language_cplus)
+           {
+             synthesize_typedef (dip, objfile, type);
+           }
+       }
+    }
+}
+
+/*
+
+   LOCAL FUNCTION
+
+   decode_array_element_type -- decode type of the array elements
+
+   SYNOPSIS
+
+   static struct type *decode_array_element_type (char *scan, char *end)
+
+   DESCRIPTION
+
+   As the last step in decoding the array subscript information for an
+   array DIE, we need to decode the type of the array elements.  We are
+   passed a pointer to this last part of the subscript information and
+   must return the appropriate type.  If the type attribute is not
+   recognized, just warn about the problem and return type int.
+ */
+
+static struct type *
+decode_array_element_type (char *scan)
+{
+  struct type *typep;
+  DIE_REF die_ref;
+  unsigned short attribute;
+  unsigned short fundtype;
+  int nbytes;
+
+  attribute = target_to_host (scan, SIZEOF_ATTRIBUTE, GET_UNSIGNED,
+                             current_objfile);
+  scan += SIZEOF_ATTRIBUTE;
+  if ((nbytes = attribute_size (attribute)) == -1)
+    {
+      complain (&bad_array_element_type, DIE_ID, DIE_NAME, attribute);
+      typep = dwarf_fundamental_type (current_objfile, FT_INTEGER);
+    }
+  else
+    {
+      switch (attribute)
+       {
+       case AT_fund_type:
+         fundtype = target_to_host (scan, nbytes, GET_UNSIGNED,
+                                    current_objfile);
+         typep = decode_fund_type (fundtype);
+         break;
+       case AT_mod_fund_type:
+         typep = decode_mod_fund_type (scan);
+         break;
+       case AT_user_def_type:
+         die_ref = target_to_host (scan, nbytes, GET_UNSIGNED,
+                                   current_objfile);
+         if ((typep = lookup_utype (die_ref)) == NULL)
+           {
+             typep = alloc_utype (die_ref, NULL);
+           }
+         break;
+       case AT_mod_u_d_type:
+         typep = decode_mod_u_d_type (scan);
+         break;
+       default:
+         complain (&bad_array_element_type, DIE_ID, DIE_NAME, attribute);
+         typep = dwarf_fundamental_type (current_objfile, FT_INTEGER);
+         break;
+       }
+    }
+  return (typep);
+}
+
+/*
+
+   LOCAL FUNCTION
+
+   decode_subscript_data_item -- decode array subscript item
+
+   SYNOPSIS
+
+   static struct type *
+   decode_subscript_data_item (char *scan, char *end)
+
+   DESCRIPTION
+
+   The array subscripts and the data type of the elements of an
+   array are described by a list of data items, stored as a block
+   of contiguous bytes.  There is a data item describing each array
+   dimension, and a final data item describing the element type.
+   The data items are ordered the same as their appearance in the
+   source (I.E. leftmost dimension first, next to leftmost second,
+   etc).
+
+   The data items describing each array dimension consist of four
+   parts: (1) a format specifier, (2) type type of the subscript
+   index, (3) a description of the low bound of the array dimension,
+   and (4) a description of the high bound of the array dimension.
+
+   The last data item is the description of the type of each of
+   the array elements.
+
+   We are passed a pointer to the start of the block of bytes
+   containing the remaining data items, and a pointer to the first
+   byte past the data.  This function recursively decodes the
+   remaining data items and returns a type.
+
+   If we somehow fail to decode some data, we complain about it
+   and return a type "array of int".
+
+   BUGS
+   FIXME:  This code only implements the forms currently used
+   by the AT&T and GNU C compilers.
+
+   The end pointer is supplied for error checking, maybe we should
+   use it for that...
+ */
+
+static struct type *
+decode_subscript_data_item (char *scan, char *end)
+{
+  struct type *typep = NULL;   /* Array type we are building */
+  struct type *nexttype;       /* Type of each element (may be array) */
+  struct type *indextype;      /* Type of this index */
+  struct type *rangetype;
+  unsigned int format;
+  unsigned short fundtype;
+  unsigned long lowbound;
+  unsigned long highbound;
+  int nbytes;
+
+  format = target_to_host (scan, SIZEOF_FORMAT_SPECIFIER, GET_UNSIGNED,
+                          current_objfile);
+  scan += SIZEOF_FORMAT_SPECIFIER;
+  switch (format)
+    {
+    case FMT_ET:
+      typep = decode_array_element_type (scan);
+      break;
+    case FMT_FT_C_C:
+      fundtype = target_to_host (scan, SIZEOF_FMT_FT, GET_UNSIGNED,
+                                current_objfile);
+      indextype = decode_fund_type (fundtype);
+      scan += SIZEOF_FMT_FT;
+      nbytes = TARGET_FT_LONG_SIZE (current_objfile);
+      lowbound = target_to_host (scan, nbytes, GET_UNSIGNED, current_objfile);
+      scan += nbytes;
+      highbound = target_to_host (scan, nbytes, GET_UNSIGNED, current_objfile);
+      scan += nbytes;
+      nexttype = decode_subscript_data_item (scan, end);
+      if (nexttype == NULL)
+       {
+         /* Munged subscript data or other problem, fake it. */
+         complain (&subscript_data_items, DIE_ID, DIE_NAME);
+         nexttype = dwarf_fundamental_type (current_objfile, FT_INTEGER);
+       }
+      rangetype = create_range_type ((struct type *) NULL, indextype,
+                                    lowbound, highbound);
+      typep = create_array_type ((struct type *) NULL, nexttype, rangetype);
+      break;
+    case FMT_FT_C_X:
+    case FMT_FT_X_C:
+    case FMT_FT_X_X:
+    case FMT_UT_C_C:
+    case FMT_UT_C_X:
+    case FMT_UT_X_C:
+    case FMT_UT_X_X:
+      complain (&unhandled_array_subscript_format, DIE_ID, DIE_NAME, format);
+      nexttype = dwarf_fundamental_type (current_objfile, FT_INTEGER);
+      rangetype = create_range_type ((struct type *) NULL, nexttype, 0, 0);
+      typep = create_array_type ((struct type *) NULL, nexttype, rangetype);
+      break;
+    default:
+      complain (&unknown_array_subscript_format, DIE_ID, DIE_NAME, format);
+      nexttype = dwarf_fundamental_type (current_objfile, FT_INTEGER);
+      rangetype = create_range_type ((struct type *) NULL, nexttype, 0, 0);
+      typep = create_array_type ((struct type *) NULL, nexttype, rangetype);
+      break;
+    }
+  return (typep);
+}
+
+/*
+
+   LOCAL FUNCTION
+
+   dwarf_read_array_type -- read TAG_array_type DIE
+
+   SYNOPSIS
+
+   static void dwarf_read_array_type (struct dieinfo *dip)
+
+   DESCRIPTION
+
+   Extract all information from a TAG_array_type DIE and add to
+   the user defined type vector.
+ */
+
+static void
+dwarf_read_array_type (struct dieinfo *dip)
+{
+  struct type *type;
+  struct type *utype;
+  char *sub;
+  char *subend;
+  unsigned short blocksz;
+  int nbytes;
+
+  if (dip->at_ordering != ORD_row_major)
+    {
+      /* FIXME:  Can gdb even handle column major arrays? */
+      complain (&not_row_major, DIE_ID, DIE_NAME);
+    }
+  if ((sub = dip->at_subscr_data) != NULL)
+    {
+      nbytes = attribute_size (AT_subscr_data);
+      blocksz = target_to_host (sub, nbytes, GET_UNSIGNED, current_objfile);
+      subend = sub + nbytes + blocksz;
+      sub += nbytes;
+      type = decode_subscript_data_item (sub, subend);
+      if ((utype = lookup_utype (dip->die_ref)) == NULL)
+       {
+         /* Install user defined type that has not been referenced yet. */
+         alloc_utype (dip->die_ref, type);
+       }
+      else if (TYPE_CODE (utype) == TYPE_CODE_UNDEF)
+       {
+         /* Ick!  A forward ref has already generated a blank type in our
+            slot, and this type probably already has things pointing to it
+            (which is what caused it to be created in the first place).
+            If it's just a place holder we can plop our fully defined type
+            on top of it.  We can't recover the space allocated for our
+            new type since it might be on an obstack, but we could reuse
+            it if we kept a list of them, but it might not be worth it
+            (FIXME). */
+         *utype = *type;
+       }
+      else
+       {
+         /* Double ick!  Not only is a type already in our slot, but
+            someone has decorated it.  Complain and leave it alone. */
+         complain (&dup_user_type_definition, DIE_ID, DIE_NAME);
+       }
+    }
+}
+
+/*
+
+   LOCAL FUNCTION
+
+   read_tag_pointer_type -- read TAG_pointer_type DIE
+
+   SYNOPSIS
+
+   static void read_tag_pointer_type (struct dieinfo *dip)
+
+   DESCRIPTION
+
+   Extract all information from a TAG_pointer_type DIE and add to
+   the user defined type vector.
+ */
+
+static void
+read_tag_pointer_type (struct dieinfo *dip)
+{
+  struct type *type;
+  struct type *utype;
+
+  type = decode_die_type (dip);
+  if ((utype = lookup_utype (dip->die_ref)) == NULL)
+    {
+      utype = lookup_pointer_type (type);
+      alloc_utype (dip->die_ref, utype);
+    }
+  else
+    {
+      TYPE_TARGET_TYPE (utype) = type;
+      TYPE_POINTER_TYPE (type) = utype;
+
+      /* We assume the machine has only one representation for pointers!  */
+      /* FIXME:  Possably a poor assumption  */
+      TYPE_LENGTH (utype) = TARGET_PTR_BIT / TARGET_CHAR_BIT;
+      TYPE_CODE (utype) = TYPE_CODE_PTR;
+    }
+}
+
+/*
+
+   LOCAL FUNCTION
+
+   read_tag_string_type -- read TAG_string_type DIE
+
+   SYNOPSIS
+
+   static void read_tag_string_type (struct dieinfo *dip)
+
+   DESCRIPTION
+
+   Extract all information from a TAG_string_type DIE and add to
+   the user defined type vector.  It isn't really a user defined
+   type, but it behaves like one, with other DIE's using an
+   AT_user_def_type attribute to reference it.
+ */
+
+static void
+read_tag_string_type (struct dieinfo *dip)
+{
+  struct type *utype;
+  struct type *indextype;
+  struct type *rangetype;
+  unsigned long lowbound = 0;
+  unsigned long highbound;
+
+  if (dip->has_at_byte_size)
+    {
+      /* A fixed bounds string */
+      highbound = dip->at_byte_size - 1;
+    }
+  else
+    {
+      /* A varying length string.  Stub for now.  (FIXME) */
+      highbound = 1;
+    }
+  indextype = dwarf_fundamental_type (current_objfile, FT_INTEGER);
+  rangetype = create_range_type ((struct type *) NULL, indextype, lowbound,
+                                highbound);
+
+  utype = lookup_utype (dip->die_ref);
+  if (utype == NULL)
+    {
+      /* No type defined, go ahead and create a blank one to use. */
+      utype = alloc_utype (dip->die_ref, (struct type *) NULL);
+    }
+  else
+    {
+      /* Already a type in our slot due to a forward reference. Make sure it
+         is a blank one.  If not, complain and leave it alone. */
+      if (TYPE_CODE (utype) != TYPE_CODE_UNDEF)
+       {
+         complain (&dup_user_type_definition, DIE_ID, DIE_NAME);
+         return;
+       }
+    }
+
+  /* Create the string type using the blank type we either found or created. */
+  utype = create_string_type (utype, rangetype);
+}
+
+/*
+
+   LOCAL FUNCTION
+
+   read_subroutine_type -- process TAG_subroutine_type dies
+
+   SYNOPSIS
+
+   static void read_subroutine_type (struct dieinfo *dip, char thisdie,
+   char *enddie)
+
+   DESCRIPTION
+
+   Handle DIES due to C code like:
+
+   struct foo {
+   int (*funcp)(int a, long l);  (Generates TAG_subroutine_type DIE)
+   int b;
+   };
+
+   NOTES
+
+   The parameter DIES are currently ignored.  See if gdb has a way to
+   include this info in it's type system, and decode them if so.  Is
+   this what the type structure's "arg_types" field is for?  (FIXME)
+ */
+
+static void
+read_subroutine_type (struct dieinfo *dip, char *thisdie, char *enddie)
+{
+  struct type *type;           /* Type that this function returns */
+  struct type *ftype;          /* Function that returns above type */
+
+  /* Decode the type that this subroutine returns */
+
+  type = decode_die_type (dip);
+
+  /* Check to see if we already have a partially constructed user
+     defined type for this DIE, from a forward reference. */
+
+  if ((ftype = lookup_utype (dip->die_ref)) == NULL)
+    {
+      /* This is the first reference to one of these types.  Make
+         a new one and place it in the user defined types. */
+      ftype = lookup_function_type (type);
+      alloc_utype (dip->die_ref, ftype);
+    }
+  else if (TYPE_CODE (ftype) == TYPE_CODE_UNDEF)
+    {
+      /* We have an existing partially constructed type, so bash it
+         into the correct type. */
+      TYPE_TARGET_TYPE (ftype) = type;
+      TYPE_LENGTH (ftype) = 1;
+      TYPE_CODE (ftype) = TYPE_CODE_FUNC;
+    }
+  else
+    {
+      complain (&dup_user_type_definition, DIE_ID, DIE_NAME);
+    }
+}
+
+/*
+
+   LOCAL FUNCTION
+
+   read_enumeration -- process dies which define an enumeration
+
+   SYNOPSIS
+
+   static void read_enumeration (struct dieinfo *dip, char *thisdie,
+   char *enddie, struct objfile *objfile)
+
+   DESCRIPTION
+
+   Given a pointer to a die which begins an enumeration, process all
+   the dies that define the members of the enumeration.
+
+   NOTES
+
+   Note that we need to call enum_type regardless of whether or not we
+   have a symbol, since we might have an enum without a tag name (thus
+   no symbol for the tagname).
+ */
+
+static void
+read_enumeration (struct dieinfo *dip, char *thisdie, char *enddie,
+                 struct objfile *objfile)
+{
+  struct type *type;
+  struct symbol *sym;
+
+  type = enum_type (dip, objfile);
+  sym = new_symbol (dip, objfile);
+  if (sym != NULL)
+    {
+      SYMBOL_TYPE (sym) = type;
+      if (cu_language == language_cplus)
+       {
+         synthesize_typedef (dip, objfile, type);
+       }
+    }
+}
+
+/*
+
+   LOCAL FUNCTION
+
+   enum_type -- decode and return a type for an enumeration
+
+   SYNOPSIS
+
+   static type *enum_type (struct dieinfo *dip, struct objfile *objfile)
+
+   DESCRIPTION
+
+   Given a pointer to a die information structure for the die which
+   starts an enumeration, process all the dies that define the members
+   of the enumeration and return a type pointer for the enumeration.
+
+   At the same time, for each member of the enumeration, create a
+   symbol for it with namespace VAR_NAMESPACE and class LOC_CONST,
+   and give it the type of the enumeration itself.
+
+   NOTES
+
+   Note that the DWARF specification explicitly mandates that enum
+   constants occur in reverse order from the source program order,
+   for "consistency" and because this ordering is easier for many
+   compilers to generate. (Draft 6, sec 3.8.5, Enumeration type
+   Entries).  Because gdb wants to see the enum members in program
+   source order, we have to ensure that the order gets reversed while
+   we are processing them.
+ */
+
+static struct type *
+enum_type (struct dieinfo *dip, struct objfile *objfile)
+{
+  struct type *type;
+  struct nextfield
+    {
+      struct nextfield *next;
+      struct field field;
+    };
+  struct nextfield *list = NULL;
+  struct nextfield *new;
+  int nfields = 0;
+  int n;
+  char *scan;
+  char *listend;
+  unsigned short blocksz;
+  struct symbol *sym;
+  int nbytes;
+  int unsigned_enum = 1;
+
+  if ((type = lookup_utype (dip->die_ref)) == NULL)
+    {
+      /* No forward references created an empty type, so install one now */
+      type = alloc_utype (dip->die_ref, NULL);
+    }
+  TYPE_CODE (type) = TYPE_CODE_ENUM;
+  /* Some compilers try to be helpful by inventing "fake" names for
+     anonymous enums, structures, and unions, like "~0fake" or ".0fake".
+     Thanks, but no thanks... */
+  if (dip->at_name != NULL
+      && *dip->at_name != '~'
+      && *dip->at_name != '.')
+    {
+      TYPE_TAG_NAME (type) = obconcat (&objfile->type_obstack,
+                                      "", "", dip->at_name);
+    }
+  if (dip->at_byte_size != 0)
+    {
+      TYPE_LENGTH (type) = dip->at_byte_size;
+    }
+  if ((scan = dip->at_element_list) != NULL)
+    {
+      if (dip->short_element_list)
+       {
+         nbytes = attribute_size (AT_short_element_list);
+       }
+      else
+       {
+         nbytes = attribute_size (AT_element_list);
+       }
+      blocksz = target_to_host (scan, nbytes, GET_UNSIGNED, objfile);
+      listend = scan + nbytes + blocksz;
+      scan += nbytes;
+      while (scan < listend)
+       {
+         new = (struct nextfield *) alloca (sizeof (struct nextfield));
+         new->next = list;
+         list = new;
+         FIELD_TYPE (list->field) = NULL;
+         FIELD_BITSIZE (list->field) = 0;
+         FIELD_BITPOS (list->field) =
+           target_to_host (scan, TARGET_FT_LONG_SIZE (objfile), GET_SIGNED,
+                           objfile);
+         scan += TARGET_FT_LONG_SIZE (objfile);
+         list->field.name = obsavestring (scan, strlen (scan),
+                                          &objfile->type_obstack);
+         scan += strlen (scan) + 1;
+         nfields++;
+         /* Handcraft a new symbol for this enum member. */
+         sym = (struct symbol *) obstack_alloc (&objfile->symbol_obstack,
+                                                sizeof (struct symbol));
+         memset (sym, 0, sizeof (struct symbol));
+         SYMBOL_NAME (sym) = create_name (list->field.name,
+                                          &objfile->symbol_obstack);
+         SYMBOL_INIT_LANGUAGE_SPECIFIC (sym, cu_language);
+         SYMBOL_NAMESPACE (sym) = VAR_NAMESPACE;
+         SYMBOL_CLASS (sym) = LOC_CONST;
+         SYMBOL_TYPE (sym) = type;
+         SYMBOL_VALUE (sym) = FIELD_BITPOS (list->field);
+         if (SYMBOL_VALUE (sym) < 0)
+           unsigned_enum = 0;
+         add_symbol_to_list (sym, list_in_scope);
+       }
+      /* Now create the vector of fields, and record how big it is. This is
+         where we reverse the order, by pulling the members off the list in
+         reverse order from how they were inserted.  If we have no fields
+         (this is apparently possible in C++) then skip building a field
+         vector. */
+      if (nfields > 0)
+       {
+         if (unsigned_enum)
+           TYPE_FLAGS (type) |= TYPE_FLAG_UNSIGNED;
+         TYPE_NFIELDS (type) = nfields;
+         TYPE_FIELDS (type) = (struct field *)
+           obstack_alloc (&objfile->symbol_obstack, sizeof (struct field) * nfields);
+         /* Copy the saved-up fields into the field vector.  */
+         for (n = 0; (n < nfields) && (list != NULL); list = list->next)
+           {
+             TYPE_FIELD (type, n++) = list->field;
+           }
+       }
+    }
+  return (type);
+}
+
+/*
+
+   LOCAL FUNCTION
+
+   read_func_scope -- process all dies within a function scope
+
+   DESCRIPTION
+
+   Process all dies within a given function scope.  We are passed
+   a die information structure pointer DIP for the die which
+   starts the function scope, and pointers into the raw die data
+   that define the dies within the function scope.
+
+   For now, we ignore lexical block scopes within the function.
+   The problem is that AT&T cc does not define a DWARF lexical
+   block scope for the function itself, while gcc defines a
+   lexical block scope for the function.  We need to think about
+   how to handle this difference, or if it is even a problem.
+   (FIXME)
+ */
+
+static void
+read_func_scope (struct dieinfo *dip, char *thisdie, char *enddie,
+                struct objfile *objfile)
+{
+  register struct context_stack *new;
+
+  /* AT_name is absent if the function is described with an
+     AT_abstract_origin tag.
+     Ignore the function description for now to avoid GDB core dumps.
+     FIXME: Add code to handle AT_abstract_origin tags properly.  */
+  if (dip->at_name == NULL)
+    {
+      complain (&missing_at_name, DIE_ID);
+      return;
+    }
+
+  if (objfile->ei.entry_point >= dip->at_low_pc &&
+      objfile->ei.entry_point < dip->at_high_pc)
+    {
+      objfile->ei.entry_func_lowpc = dip->at_low_pc;
+      objfile->ei.entry_func_highpc = dip->at_high_pc;
+    }
+  new = push_context (0, dip->at_low_pc);
+  new->name = new_symbol (dip, objfile);
+  list_in_scope = &local_symbols;
+  process_dies (thisdie + dip->die_length, enddie, objfile);
+  new = pop_context ();
+  /* Make a block for the local symbols within.  */
+  finish_block (new->name, &local_symbols, new->old_blocks,
+               new->start_addr, dip->at_high_pc, objfile);
+  list_in_scope = &file_symbols;
+}
+
+
+/*
+
+   LOCAL FUNCTION
+
+   handle_producer -- process the AT_producer attribute
+
+   DESCRIPTION
+
+   Perform any operations that depend on finding a particular
+   AT_producer attribute.
+
+ */
+
+static void
+handle_producer (char *producer)
+{
+
+  /* If this compilation unit was compiled with g++ or gcc, then set the
+     processing_gcc_compilation flag. */
+
+  if (STREQN (producer, GCC_PRODUCER, strlen (GCC_PRODUCER)))
+    {
+      char version = producer[strlen (GCC_PRODUCER)];
+      processing_gcc_compilation = (version == '2' ? 2 : 1);
+    }
+  else
+    {
+      processing_gcc_compilation =
+       STREQN (producer, GPLUS_PRODUCER, strlen (GPLUS_PRODUCER));
+      /* OBSOLETE || STREQN (producer, CHILL_PRODUCER, strlen (CHILL_PRODUCER)); */
+    }
+
+  /* Select a demangling style if we can identify the producer and if
+     the current style is auto.  We leave the current style alone if it
+     is not auto.  We also leave the demangling style alone if we find a
+     gcc (cc1) producer, as opposed to a g++ (cc1plus) producer. */
+
+  if (AUTO_DEMANGLING)
+    {
+      if (STREQN (producer, GPLUS_PRODUCER, strlen (GPLUS_PRODUCER)))
+       {
+#if 0
+         /* For now, stay with AUTO_DEMANGLING for g++ output, as we don't
+            know whether it will use the old style or v3 mangling.  */
+         set_demangling_style (GNU_DEMANGLING_STYLE_STRING);
+#endif
+       }
+      else if (STREQN (producer, LCC_PRODUCER, strlen (LCC_PRODUCER)))
+       {
+         set_demangling_style (LUCID_DEMANGLING_STYLE_STRING);
+       }
+    }
+}
+
+
+/*
+
+   LOCAL FUNCTION
+
+   read_file_scope -- process all dies within a file scope
+
+   DESCRIPTION
+
+   Process all dies within a given file scope.  We are passed a
+   pointer to the die information structure for the die which
+   starts the file scope, and pointers into the raw die data which
+   mark the range of dies within the file scope.
+
+   When the partial symbol table is built, the file offset for the line
+   number table for each compilation unit is saved in the partial symbol
+   table entry for that compilation unit.  As the symbols for each
+   compilation unit are read, the line number table is read into memory
+   and the variable lnbase is set to point to it.  Thus all we have to
+   do is use lnbase to access the line number table for the current
+   compilation unit.
+ */
+
+static void
+read_file_scope (struct dieinfo *dip, char *thisdie, char *enddie,
+                struct objfile *objfile)
+{
+  struct cleanup *back_to;
+  struct symtab *symtab;
+
+  if (objfile->ei.entry_point >= dip->at_low_pc &&
+      objfile->ei.entry_point < dip->at_high_pc)
+    {
+      objfile->ei.entry_file_lowpc = dip->at_low_pc;
+      objfile->ei.entry_file_highpc = dip->at_high_pc;
+    }
+  set_cu_language (dip);
+  if (dip->at_producer != NULL)
+    {
+      handle_producer (dip->at_producer);
+    }
+  numutypes = (enddie - thisdie) / 4;
+  utypes = (struct type **) xmalloc (numutypes * sizeof (struct type *));
+  back_to = make_cleanup (free_utypes, NULL);
+  memset (utypes, 0, numutypes * sizeof (struct type *));
+  memset (ftypes, 0, FT_NUM_MEMBERS * sizeof (struct type *));
+  start_symtab (dip->at_name, dip->at_comp_dir, dip->at_low_pc);
+  record_debugformat ("DWARF 1");
+  decode_line_numbers (lnbase);
+  process_dies (thisdie + dip->die_length, enddie, objfile);
+
+  symtab = end_symtab (dip->at_high_pc, objfile, 0);
+  if (symtab != NULL)
+    {
+      symtab->language = cu_language;
+    }
+  do_cleanups (back_to);
+}
+
+/*
+
+   LOCAL FUNCTION
+
+   process_dies -- process a range of DWARF Information Entries
+
+   SYNOPSIS
+
+   static void process_dies (char *thisdie, char *enddie,
+   struct objfile *objfile)
+
+   DESCRIPTION
+
+   Process all DIE's in a specified range.  May be (and almost
+   certainly will be) called recursively.
+ */
+
+static void
+process_dies (char *thisdie, char *enddie, struct objfile *objfile)
+{
+  char *nextdie;
+  struct dieinfo di;
+
+  while (thisdie < enddie)
+    {
+      basicdieinfo (&di, thisdie, objfile);
+      if (di.die_length < SIZEOF_DIE_LENGTH)
+       {
+         break;
+       }
+      else if (di.die_tag == TAG_padding)
+       {
+         nextdie = thisdie + di.die_length;
+       }
+      else
+       {
+         completedieinfo (&di, objfile);
+         if (di.at_sibling != 0)
+           {
+             nextdie = dbbase + di.at_sibling - dbroff;
+           }
+         else
+           {
+             nextdie = thisdie + di.die_length;
+           }
+         /* I think that these are always text, not data, addresses.  */
+         di.at_low_pc = SMASH_TEXT_ADDRESS (di.at_low_pc);
+         di.at_high_pc = SMASH_TEXT_ADDRESS (di.at_high_pc);
+         switch (di.die_tag)
+           {
+           case TAG_compile_unit:
+             /* Skip Tag_compile_unit if we are already inside a compilation
+                unit, we are unable to handle nested compilation units
+                properly (FIXME).  */
+             if (current_subfile == NULL)
+               read_file_scope (&di, thisdie, nextdie, objfile);
+             else
+               nextdie = thisdie + di.die_length;
+             break;
+           case TAG_global_subroutine:
+           case TAG_subroutine:
+             if (di.has_at_low_pc)
+               {
+                 read_func_scope (&di, thisdie, nextdie, objfile);
+               }
+             break;
+           case TAG_lexical_block:
+             read_lexical_block_scope (&di, thisdie, nextdie, objfile);
+             break;
+           case TAG_class_type:
+           case TAG_structure_type:
+           case TAG_union_type:
+             read_structure_scope (&di, thisdie, nextdie, objfile);
+             break;
+           case TAG_enumeration_type:
+             read_enumeration (&di, thisdie, nextdie, objfile);
+             break;
+           case TAG_subroutine_type:
+             read_subroutine_type (&di, thisdie, nextdie);
+             break;
+           case TAG_array_type:
+             dwarf_read_array_type (&di);
+             break;
+           case TAG_pointer_type:
+             read_tag_pointer_type (&di);
+             break;
+           case TAG_string_type:
+             read_tag_string_type (&di);
+             break;
+           default:
+             new_symbol (&di, objfile);
+             break;
+           }
+       }
+      thisdie = nextdie;
+    }
+}
+
+/*
+
+   LOCAL FUNCTION
+
+   decode_line_numbers -- decode a line number table fragment
+
+   SYNOPSIS
+
+   static void decode_line_numbers (char *tblscan, char *tblend,
+   long length, long base, long line, long pc)
+
+   DESCRIPTION
+
+   Translate the DWARF line number information to gdb form.
+
+   The ".line" section contains one or more line number tables, one for
+   each ".line" section from the objects that were linked.
+
+   The AT_stmt_list attribute for each TAG_source_file entry in the
+   ".debug" section contains the offset into the ".line" section for the
+   start of the table for that file.
+
+   The table itself has the following structure:
+
+   <table length><base address><source statement entry>
+   4 bytes       4 bytes       10 bytes
+
+   The table length is the total size of the table, including the 4 bytes
+   for the length information.
+
+   The base address is the address of the first instruction generated
+   for the source file.
+
+   Each source statement entry has the following structure:
+
+   <line number><statement position><address delta>
+   4 bytes      2 bytes             4 bytes
+
+   The line number is relative to the start of the file, starting with
+   line 1.
+
+   The statement position either -1 (0xFFFF) or the number of characters
+   from the beginning of the line to the beginning of the statement.
+
+   The address delta is the difference between the base address and
+   the address of the first instruction for the statement.
+
+   Note that we must copy the bytes from the packed table to our local
+   variables before attempting to use them, to avoid alignment problems
+   on some machines, particularly RISC processors.
+
+   BUGS
+
+   Does gdb expect the line numbers to be sorted?  They are now by
+   chance/luck, but are not required to be.  (FIXME)
+
+   The line with number 0 is unused, gdb apparently can discover the
+   span of the last line some other way. How?  (FIXME)
+ */
+
+static void
+decode_line_numbers (char *linetable)
+{
+  char *tblscan;
+  char *tblend;
+  unsigned long length;
+  unsigned long base;
+  unsigned long line;
+  unsigned long pc;
+
+  if (linetable != NULL)
+    {
+      tblscan = tblend = linetable;
+      length = target_to_host (tblscan, SIZEOF_LINETBL_LENGTH, GET_UNSIGNED,
+                              current_objfile);
+      tblscan += SIZEOF_LINETBL_LENGTH;
+      tblend += length;
+      base = target_to_host (tblscan, TARGET_FT_POINTER_SIZE (objfile),
+                            GET_UNSIGNED, current_objfile);
+      tblscan += TARGET_FT_POINTER_SIZE (objfile);
+      base += baseaddr;
+      while (tblscan < tblend)
+       {
+         line = target_to_host (tblscan, SIZEOF_LINETBL_LINENO, GET_UNSIGNED,
+                                current_objfile);
+         tblscan += SIZEOF_LINETBL_LINENO + SIZEOF_LINETBL_STMT;
+         pc = target_to_host (tblscan, SIZEOF_LINETBL_DELTA, GET_UNSIGNED,
+                              current_objfile);
+         tblscan += SIZEOF_LINETBL_DELTA;
+         pc += base;
+         if (line != 0)
+           {
+             record_line (current_subfile, line, pc);
+           }
+       }
+    }
+}
+
+/*
+
+   LOCAL FUNCTION
+
+   locval -- compute the value of a location attribute
+
+   SYNOPSIS
+
+   static int locval (struct dieinfo *dip)
+
+   DESCRIPTION
+
+   Given pointer to a string of bytes that define a location, compute
+   the location and return the value.
+   A location description containing no atoms indicates that the
+   object is optimized out. The optimized_out flag is set for those,
+   the return value is meaningless.
+
+   When computing values involving the current value of the frame pointer,
+   the value zero is used, which results in a value relative to the frame
+   pointer, rather than the absolute value.  This is what GDB wants
+   anyway.
+
+   When the result is a register number, the isreg flag is set, otherwise
+   it is cleared.  This is a kludge until we figure out a better
+   way to handle the problem.  Gdb's design does not mesh well with the
+   DWARF notion of a location computing interpreter, which is a shame
+   because the flexibility goes unused.
+
+   NOTES
+
+   Note that stack[0] is unused except as a default error return.
+   Note that stack overflow is not yet handled.
+ */
+
+static int
+locval (struct dieinfo *dip)
+{
+  unsigned short nbytes;
+  unsigned short locsize;
+  auto long stack[64];
+  int stacki;
+  char *loc;
+  char *end;
+  int loc_atom_code;
+  int loc_value_size;
+
+  loc = dip->at_location;
+  nbytes = attribute_size (AT_location);
+  locsize = target_to_host (loc, nbytes, GET_UNSIGNED, current_objfile);
+  loc += nbytes;
+  end = loc + locsize;
+  stacki = 0;
+  stack[stacki] = 0;
+  dip->isreg = 0;
+  dip->offreg = 0;
+  dip->optimized_out = 1;
+  loc_value_size = TARGET_FT_LONG_SIZE (current_objfile);
+  while (loc < end)
+    {
+      dip->optimized_out = 0;
+      loc_atom_code = target_to_host (loc, SIZEOF_LOC_ATOM_CODE, GET_UNSIGNED,
+                                     current_objfile);
+      loc += SIZEOF_LOC_ATOM_CODE;
+      switch (loc_atom_code)
+       {
+       case 0:
+         /* error */
+         loc = end;
+         break;
+       case OP_REG:
+         /* push register (number) */
+         stack[++stacki]
+           = DWARF_REG_TO_REGNUM (target_to_host (loc, loc_value_size,
+                                                  GET_UNSIGNED,
+                                                  current_objfile));
+         loc += loc_value_size;
+         dip->isreg = 1;
+         break;
+       case OP_BASEREG:
+         /* push value of register (number) */
+         /* Actually, we compute the value as if register has 0, so the
+            value ends up being the offset from that register.  */
+         dip->offreg = 1;
+         dip->basereg = target_to_host (loc, loc_value_size, GET_UNSIGNED,
+                                        current_objfile);
+         loc += loc_value_size;
+         stack[++stacki] = 0;
+         break;
+       case OP_ADDR:
+         /* push address (relocated address) */
+         stack[++stacki] = target_to_host (loc, loc_value_size,
+                                           GET_UNSIGNED, current_objfile);
+         loc += loc_value_size;
+         break;
+       case OP_CONST:
+         /* push constant (number)   FIXME: signed or unsigned! */
+         stack[++stacki] = target_to_host (loc, loc_value_size,
+                                           GET_SIGNED, current_objfile);
+         loc += loc_value_size;
+         break;
+       case OP_DEREF2:
+         /* pop, deref and push 2 bytes (as a long) */
+         complain (&op_deref2, DIE_ID, DIE_NAME, stack[stacki]);
+         break;
+       case OP_DEREF4: /* pop, deref and push 4 bytes (as a long) */
+         complain (&op_deref4, DIE_ID, DIE_NAME, stack[stacki]);
+         break;
+       case OP_ADD:            /* pop top 2 items, add, push result */
+         stack[stacki - 1] += stack[stacki];
+         stacki--;
+         break;
+       }
+    }
+  return (stack[stacki]);
+}
+
+/*
+
+   LOCAL FUNCTION
+
+   read_ofile_symtab -- build a full symtab entry from chunk of DIE's
+
+   SYNOPSIS
+
+   static void read_ofile_symtab (struct partial_symtab *pst)
+
+   DESCRIPTION
+
+   When expanding a partial symbol table entry to a full symbol table
+   entry, this is the function that gets called to read in the symbols
+   for the compilation unit.  A pointer to the newly constructed symtab,
+   which is now the new first one on the objfile's symtab list, is
+   stashed in the partial symbol table entry.
+ */
+
+static void
+read_ofile_symtab (struct partial_symtab *pst)
+{
+  struct cleanup *back_to;
+  unsigned long lnsize;
+  file_ptr foffset;
+  bfd *abfd;
+  char lnsizedata[SIZEOF_LINETBL_LENGTH];
+
+  abfd = pst->objfile->obfd;
+  current_objfile = pst->objfile;
+
+  /* Allocate a buffer for the entire chunk of DIE's for this compilation
+     unit, seek to the location in the file, and read in all the DIE's. */
+
+  diecount = 0;
+  dbsize = DBLENGTH (pst);
+  dbbase = xmalloc (dbsize);
+  dbroff = DBROFF (pst);
+  foffset = DBFOFF (pst) + dbroff;
+  base_section_offsets = pst->section_offsets;
+  baseaddr = ANOFFSET (pst->section_offsets, 0);
+  if (bfd_seek (abfd, foffset, SEEK_SET) ||
+      (bfd_bread (dbbase, dbsize, abfd) != dbsize))
+    {
+      xfree (dbbase);
+      error ("can't read DWARF data");
+    }
+  back_to = make_cleanup (xfree, dbbase);
+
+  /* If there is a line number table associated with this compilation unit
+     then read the size of this fragment in bytes, from the fragment itself.
+     Allocate a buffer for the fragment and read it in for future 
+     processing. */
+
+  lnbase = NULL;
+  if (LNFOFF (pst))
+    {
+      if (bfd_seek (abfd, LNFOFF (pst), SEEK_SET) ||
+         (bfd_bread ((PTR) lnsizedata, sizeof (lnsizedata), abfd)
+          != sizeof (lnsizedata)))
+       {
+         error ("can't read DWARF line number table size");
+       }
+      lnsize = target_to_host (lnsizedata, SIZEOF_LINETBL_LENGTH,
+                              GET_UNSIGNED, pst->objfile);
+      lnbase = xmalloc (lnsize);
+      if (bfd_seek (abfd, LNFOFF (pst), SEEK_SET) ||
+         (bfd_bread (lnbase, lnsize, abfd) != lnsize))
+       {
+         xfree (lnbase);
+         error ("can't read DWARF line numbers");
+       }
+      make_cleanup (xfree, lnbase);
+    }
+
+  process_dies (dbbase, dbbase + dbsize, pst->objfile);
+  do_cleanups (back_to);
+  current_objfile = NULL;
+  pst->symtab = pst->objfile->symtabs;
+}
+
+/*
+
+   LOCAL FUNCTION
+
+   psymtab_to_symtab_1 -- do grunt work for building a full symtab entry
+
+   SYNOPSIS
+
+   static void psymtab_to_symtab_1 (struct partial_symtab *pst)
+
+   DESCRIPTION
+
+   Called once for each partial symbol table entry that needs to be
+   expanded into a full symbol table entry.
+
+ */
+
+static void
+psymtab_to_symtab_1 (struct partial_symtab *pst)
+{
+  int i;
+  struct cleanup *old_chain;
+
+  if (pst != NULL)
+    {
+      if (pst->readin)
+       {
+         warning ("psymtab for %s already read in.  Shouldn't happen.",
+                  pst->filename);
+       }
+      else
+       {
+         /* Read in all partial symtabs on which this one is dependent */
+         for (i = 0; i < pst->number_of_dependencies; i++)
+           {
+             if (!pst->dependencies[i]->readin)
+               {
+                 /* Inform about additional files that need to be read in. */
+                 if (info_verbose)
+                   {
+                     fputs_filtered (" ", gdb_stdout);
+                     wrap_here ("");
+                     fputs_filtered ("and ", gdb_stdout);
+                     wrap_here ("");
+                     printf_filtered ("%s...",
+                                      pst->dependencies[i]->filename);
+                     wrap_here ("");
+                     gdb_flush (gdb_stdout);   /* Flush output */
+                   }
+                 psymtab_to_symtab_1 (pst->dependencies[i]);
+               }
+           }
+         if (DBLENGTH (pst))   /* Otherwise it's a dummy */
+           {
+             buildsym_init ();
+             old_chain = make_cleanup (really_free_pendings, 0);
+             read_ofile_symtab (pst);
+             if (info_verbose)
+               {
+                 printf_filtered ("%d DIE's, sorting...", diecount);
+                 wrap_here ("");
+                 gdb_flush (gdb_stdout);
+               }
+             sort_symtab_syms (pst->symtab);
+             do_cleanups (old_chain);
+           }
+         pst->readin = 1;
+       }
+    }
+}
+
+/*
+
+   LOCAL FUNCTION
+
+   dwarf_psymtab_to_symtab -- build a full symtab entry from partial one
+
+   SYNOPSIS
+
+   static void dwarf_psymtab_to_symtab (struct partial_symtab *pst)
+
+   DESCRIPTION
+
+   This is the DWARF support entry point for building a full symbol
+   table entry from a partial symbol table entry.  We are passed a
+   pointer to the partial symbol table entry that needs to be expanded.
+
+ */
+
+static void
+dwarf_psymtab_to_symtab (struct partial_symtab *pst)
+{
+
+  if (pst != NULL)
+    {
+      if (pst->readin)
+       {
+         warning ("psymtab for %s already read in.  Shouldn't happen.",
+                  pst->filename);
+       }
+      else
+       {
+         if (DBLENGTH (pst) || pst->number_of_dependencies)
+           {
+             /* Print the message now, before starting serious work, to avoid
+                disconcerting pauses.  */
+             if (info_verbose)
+               {
+                 printf_filtered ("Reading in symbols for %s...",
+                                  pst->filename);
+                 gdb_flush (gdb_stdout);
+               }
+
+             psymtab_to_symtab_1 (pst);
+
+#if 0                          /* FIXME:  Check to see what dbxread is doing here and see if
+                                  we need to do an equivalent or is this something peculiar to
+                                  stabs/a.out format.
+                                  Match with global symbols.  This only needs to be done once,
+                                  after all of the symtabs and dependencies have been read in.
+                                */
+             scan_file_globals (pst->objfile);
+#endif
+
+             /* Finish up the verbose info message.  */
+             if (info_verbose)
+               {
+                 printf_filtered ("done.\n");
+                 gdb_flush (gdb_stdout);
+               }
+           }
+       }
+    }
+}
+
+/*
+
+   LOCAL FUNCTION
+
+   add_enum_psymbol -- add enumeration members to partial symbol table
+
+   DESCRIPTION
+
+   Given pointer to a DIE that is known to be for an enumeration,
+   extract the symbolic names of the enumeration members and add
+   partial symbols for them.
+ */
+
+static void
+add_enum_psymbol (struct dieinfo *dip, struct objfile *objfile)
+{
+  char *scan;
+  char *listend;
+  unsigned short blocksz;
+  int nbytes;
+
+  if ((scan = dip->at_element_list) != NULL)
+    {
+      if (dip->short_element_list)
+       {
+         nbytes = attribute_size (AT_short_element_list);
+       }
+      else
+       {
+         nbytes = attribute_size (AT_element_list);
+       }
+      blocksz = target_to_host (scan, nbytes, GET_UNSIGNED, objfile);
+      scan += nbytes;
+      listend = scan + blocksz;
+      while (scan < listend)
+       {
+         scan += TARGET_FT_LONG_SIZE (objfile);
+         add_psymbol_to_list (scan, strlen (scan), VAR_NAMESPACE, LOC_CONST,
+                              &objfile->static_psymbols, 0, 0, cu_language,
+                              objfile);
+         scan += strlen (scan) + 1;
+       }
+    }
+}
+
+/*
+
+   LOCAL FUNCTION
+
+   add_partial_symbol -- add symbol to partial symbol table
+
+   DESCRIPTION
+
+   Given a DIE, if it is one of the types that we want to
+   add to a partial symbol table, finish filling in the die info
+   and then add a partial symbol table entry for it.
+
+   NOTES
+
+   The caller must ensure that the DIE has a valid name attribute.
+ */
+
+static void
+add_partial_symbol (struct dieinfo *dip, struct objfile *objfile)
+{
+  switch (dip->die_tag)
+    {
+    case TAG_global_subroutine:
+      add_psymbol_to_list (dip->at_name, strlen (dip->at_name),
+                          VAR_NAMESPACE, LOC_BLOCK,
+                          &objfile->global_psymbols,
+                          0, dip->at_low_pc, cu_language, objfile);
+      break;
+    case TAG_global_variable:
+      add_psymbol_to_list (dip->at_name, strlen (dip->at_name),
+                          VAR_NAMESPACE, LOC_STATIC,
+                          &objfile->global_psymbols,
+                          0, 0, cu_language, objfile);
+      break;
+    case TAG_subroutine:
+      add_psymbol_to_list (dip->at_name, strlen (dip->at_name),
+                          VAR_NAMESPACE, LOC_BLOCK,
+                          &objfile->static_psymbols,
+                          0, dip->at_low_pc, cu_language, objfile);
+      break;
+    case TAG_local_variable:
+      add_psymbol_to_list (dip->at_name, strlen (dip->at_name),
+                          VAR_NAMESPACE, LOC_STATIC,
+                          &objfile->static_psymbols,
+                          0, 0, cu_language, objfile);
+      break;
+    case TAG_typedef:
+      add_psymbol_to_list (dip->at_name, strlen (dip->at_name),
+                          VAR_NAMESPACE, LOC_TYPEDEF,
+                          &objfile->static_psymbols,
+                          0, 0, cu_language, objfile);
+      break;
+    case TAG_class_type:
+    case TAG_structure_type:
+    case TAG_union_type:
+    case TAG_enumeration_type:
+      /* Do not add opaque aggregate definitions to the psymtab.  */
+      if (!dip->has_at_byte_size)
+       break;
+      add_psymbol_to_list (dip->at_name, strlen (dip->at_name),
+                          STRUCT_NAMESPACE, LOC_TYPEDEF,
+                          &objfile->static_psymbols,
+                          0, 0, cu_language, objfile);
+      if (cu_language == language_cplus)
+       {
+         /* For C++, these implicitly act as typedefs as well. */
+         add_psymbol_to_list (dip->at_name, strlen (dip->at_name),
+                              VAR_NAMESPACE, LOC_TYPEDEF,
+                              &objfile->static_psymbols,
+                              0, 0, cu_language, objfile);
+       }
+      break;
+    }
+}
+/* *INDENT-OFF* */
+/*
+
+LOCAL FUNCTION
+
+       scan_partial_symbols -- scan DIE's within a single compilation unit
+
+DESCRIPTION
+
+       Process the DIE's within a single compilation unit, looking for
+       interesting DIE's that contribute to the partial symbol table entry
+       for this compilation unit.
+
+NOTES
+
+       There are some DIE's that may appear both at file scope and within
+       the scope of a function.  We are only interested in the ones at file
+       scope, and the only way to tell them apart is to keep track of the
+       scope.  For example, consider the test case:
+
+               static int i;
+               main () { int j; }
+
+       for which the relevant DWARF segment has the structure:
+       
+               0x51:
+               0x23   global subrtn   sibling     0x9b
+                                      name        main
+                                      fund_type   FT_integer
+                                      low_pc      0x800004cc
+                                      high_pc     0x800004d4
+                                           
+               0x74:
+               0x23   local var       sibling     0x97
+                                      name        j
+                                      fund_type   FT_integer
+                                      location    OP_BASEREG 0xe
+                                                  OP_CONST 0xfffffffc
+                                                  OP_ADD
+               0x97:
+               0x4         
+               
+               0x9b:
+               0x1d   local var       sibling     0xb8
+                                      name        i
+                                      fund_type   FT_integer
+                                      location    OP_ADDR 0x800025dc
+                                           
+               0xb8:
+               0x4         
+
+       We want to include the symbol 'i' in the partial symbol table, but
+       not the symbol 'j'.  In essence, we want to skip all the dies within
+       the scope of a TAG_global_subroutine DIE.
+
+       Don't attempt to add anonymous structures or unions since they have
+       no name.  Anonymous enumerations however are processed, because we
+       want to extract their member names (the check for a tag name is
+       done later).
+
+       Also, for variables and subroutines, check that this is the place
+       where the actual definition occurs, rather than just a reference
+       to an external.
+ */
+/* *INDENT-ON* */
+
+
+
+static void
+scan_partial_symbols (char *thisdie, char *enddie, struct objfile *objfile)
+{
+  char *nextdie;
+  char *temp;
+  struct dieinfo di;
+
+  while (thisdie < enddie)
+    {
+      basicdieinfo (&di, thisdie, objfile);
+      if (di.die_length < SIZEOF_DIE_LENGTH)
+       {
+         break;
+       }
+      else
+       {
+         nextdie = thisdie + di.die_length;
+         /* To avoid getting complete die information for every die, we
+            only do it (below) for the cases we are interested in. */
+         switch (di.die_tag)
+           {
+           case TAG_global_subroutine:
+           case TAG_subroutine:
+             completedieinfo (&di, objfile);
+             if (di.at_name && (di.has_at_low_pc || di.at_location))
+               {
+                 add_partial_symbol (&di, objfile);
+                 /* If there is a sibling attribute, adjust the nextdie
+                    pointer to skip the entire scope of the subroutine.
+                    Apply some sanity checking to make sure we don't 
+                    overrun or underrun the range of remaining DIE's */
+                 if (di.at_sibling != 0)
+                   {
+                     temp = dbbase + di.at_sibling - dbroff;
+                     if ((temp < thisdie) || (temp >= enddie))
+                       {
+                         complain (&bad_die_ref, DIE_ID, DIE_NAME,
+                                   di.at_sibling);
+                       }
+                     else
+                       {
+                         nextdie = temp;
+                       }
+                   }
+               }
+             break;
+           case TAG_global_variable:
+           case TAG_local_variable:
+             completedieinfo (&di, objfile);
+             if (di.at_name && (di.has_at_low_pc || di.at_location))
+               {
+                 add_partial_symbol (&di, objfile);
+               }
+             break;
+           case TAG_typedef:
+           case TAG_class_type:
+           case TAG_structure_type:
+           case TAG_union_type:
+             completedieinfo (&di, objfile);
+             if (di.at_name)
+               {
+                 add_partial_symbol (&di, objfile);
+               }
+             break;
+           case TAG_enumeration_type:
+             completedieinfo (&di, objfile);
+             if (di.at_name)
+               {
+                 add_partial_symbol (&di, objfile);
+               }
+             add_enum_psymbol (&di, objfile);
+             break;
+           }
+       }
+      thisdie = nextdie;
+    }
+}
+
+/*
+
+   LOCAL FUNCTION
+
+   scan_compilation_units -- build a psymtab entry for each compilation
+
+   DESCRIPTION
+
+   This is the top level dwarf parsing routine for building partial
+   symbol tables.
+
+   It scans from the beginning of the DWARF table looking for the first
+   TAG_compile_unit DIE, and then follows the sibling chain to locate
+   each additional TAG_compile_unit DIE.
+
+   For each TAG_compile_unit DIE it creates a partial symtab structure,
+   calls a subordinate routine to collect all the compilation unit's
+   global DIE's, file scope DIEs, typedef DIEs, etc, and then links the
+   new partial symtab structure into the partial symbol table.  It also
+   records the appropriate information in the partial symbol table entry
+   to allow the chunk of DIE's and line number table for this compilation
+   unit to be located and re-read later, to generate a complete symbol
+   table entry for the compilation unit.
+
+   Thus it effectively partitions up a chunk of DIE's for multiple
+   compilation units into smaller DIE chunks and line number tables,
+   and associates them with a partial symbol table entry.
+
+   NOTES
+
+   If any compilation unit has no line number table associated with
+   it for some reason (a missing at_stmt_list attribute, rather than
+   just one with a value of zero, which is valid) then we ensure that
+   the recorded file offset is zero so that the routine which later
+   reads line number table fragments knows that there is no fragment
+   to read.
+
+   RETURNS
+
+   Returns no value.
+
+ */
+
+static void
+scan_compilation_units (char *thisdie, char *enddie, file_ptr dbfoff,
+                       file_ptr lnoffset, struct objfile *objfile)
+{
+  char *nextdie;
+  struct dieinfo di;
+  struct partial_symtab *pst;
+  int culength;
+  int curoff;
+  file_ptr curlnoffset;
+
+  while (thisdie < enddie)
+    {
+      basicdieinfo (&di, thisdie, objfile);
+      if (di.die_length < SIZEOF_DIE_LENGTH)
+       {
+         break;
+       }
+      else if (di.die_tag != TAG_compile_unit)
+       {
+         nextdie = thisdie + di.die_length;
+       }
+      else
+       {
+         completedieinfo (&di, objfile);
+         set_cu_language (&di);
+         if (di.at_sibling != 0)
+           {
+             nextdie = dbbase + di.at_sibling - dbroff;
+           }
+         else
+           {
+             nextdie = thisdie + di.die_length;
+           }
+         curoff = thisdie - dbbase;
+         culength = nextdie - thisdie;
+         curlnoffset = di.has_at_stmt_list ? lnoffset + di.at_stmt_list : 0;
+
+         /* First allocate a new partial symbol table structure */
+
+         pst = start_psymtab_common (objfile, base_section_offsets,
+                                     di.at_name, di.at_low_pc,
+                                     objfile->global_psymbols.next,
+                                     objfile->static_psymbols.next);
+
+         pst->texthigh = di.at_high_pc;
+         pst->read_symtab_private = (char *)
+           obstack_alloc (&objfile->psymbol_obstack,
+                          sizeof (struct dwfinfo));
+         DBFOFF (pst) = dbfoff;
+         DBROFF (pst) = curoff;
+         DBLENGTH (pst) = culength;
+         LNFOFF (pst) = curlnoffset;
+         pst->read_symtab = dwarf_psymtab_to_symtab;
+
+         /* Now look for partial symbols */
+
+         scan_partial_symbols (thisdie + di.die_length, nextdie, objfile);
+
+         pst->n_global_syms = objfile->global_psymbols.next -
+           (objfile->global_psymbols.list + pst->globals_offset);
+         pst->n_static_syms = objfile->static_psymbols.next -
+           (objfile->static_psymbols.list + pst->statics_offset);
+         sort_pst_symbols (pst);
+         /* If there is already a psymtab or symtab for a file of this name,
+            remove it. (If there is a symtab, more drastic things also
+            happen.)  This happens in VxWorks.  */
+         free_named_symtabs (pst->filename);
+       }
+      thisdie = nextdie;
+    }
+}
+
+/*
+
+   LOCAL FUNCTION
+
+   new_symbol -- make a symbol table entry for a new symbol
+
+   SYNOPSIS
+
+   static struct symbol *new_symbol (struct dieinfo *dip,
+   struct objfile *objfile)
+
+   DESCRIPTION
+
+   Given a pointer to a DWARF information entry, figure out if we need
+   to make a symbol table entry for it, and if so, create a new entry
+   and return a pointer to it.
+ */
+
+static struct symbol *
+new_symbol (struct dieinfo *dip, struct objfile *objfile)
+{
+  struct symbol *sym = NULL;
+
+  if (dip->at_name != NULL)
+    {
+      sym = (struct symbol *) obstack_alloc (&objfile->symbol_obstack,
+                                            sizeof (struct symbol));
+      OBJSTAT (objfile, n_syms++);
+      memset (sym, 0, sizeof (struct symbol));
+      SYMBOL_NAME (sym) = create_name (dip->at_name,
+                                      &objfile->symbol_obstack);
+      /* default assumptions */
+      SYMBOL_NAMESPACE (sym) = VAR_NAMESPACE;
+      SYMBOL_CLASS (sym) = LOC_STATIC;
+      SYMBOL_TYPE (sym) = decode_die_type (dip);
+
+      /* If this symbol is from a C++ compilation, then attempt to cache the
+         demangled form for future reference.  This is a typical time versus
+         space tradeoff, that was decided in favor of time because it sped up
+         C++ symbol lookups by a factor of about 20. */
+
+      SYMBOL_LANGUAGE (sym) = cu_language;
+      SYMBOL_INIT_DEMANGLED_NAME (sym, &objfile->symbol_obstack);
+      switch (dip->die_tag)
+       {
+       case TAG_label:
+         SYMBOL_VALUE_ADDRESS (sym) = dip->at_low_pc;
+         SYMBOL_CLASS (sym) = LOC_LABEL;
+         break;
+       case TAG_global_subroutine:
+       case TAG_subroutine:
+         SYMBOL_VALUE_ADDRESS (sym) = dip->at_low_pc;
+         SYMBOL_TYPE (sym) = lookup_function_type (SYMBOL_TYPE (sym));
+         if (dip->at_prototyped)
+           TYPE_FLAGS (SYMBOL_TYPE (sym)) |= TYPE_FLAG_PROTOTYPED;
+         SYMBOL_CLASS (sym) = LOC_BLOCK;
+         if (dip->die_tag == TAG_global_subroutine)
+           {
+             add_symbol_to_list (sym, &global_symbols);
+           }
+         else
+           {
+             add_symbol_to_list (sym, list_in_scope);
+           }
+         break;
+       case TAG_global_variable:
+         if (dip->at_location != NULL)
+           {
+             SYMBOL_VALUE_ADDRESS (sym) = locval (dip);
+             add_symbol_to_list (sym, &global_symbols);
+             SYMBOL_CLASS (sym) = LOC_STATIC;
+             SYMBOL_VALUE (sym) += baseaddr;
+           }
+         break;
+       case TAG_local_variable:
+         if (dip->at_location != NULL)
+           {
+             int loc = locval (dip);
+             if (dip->optimized_out)
+               {
+                 SYMBOL_CLASS (sym) = LOC_OPTIMIZED_OUT;
+               }
+             else if (dip->isreg)
+               {
+                 SYMBOL_CLASS (sym) = LOC_REGISTER;
+               }
+             else if (dip->offreg)
+               {
+                 SYMBOL_CLASS (sym) = LOC_BASEREG;
+                 SYMBOL_BASEREG (sym) = dip->basereg;
+               }
+             else
+               {
+                 SYMBOL_CLASS (sym) = LOC_STATIC;
+                 SYMBOL_VALUE (sym) += baseaddr;
+               }
+             if (SYMBOL_CLASS (sym) == LOC_STATIC)
+               {
+                 /* LOC_STATIC address class MUST use SYMBOL_VALUE_ADDRESS,
+                    which may store to a bigger location than SYMBOL_VALUE. */
+                 SYMBOL_VALUE_ADDRESS (sym) = loc;
+               }
+             else
+               {
+                 SYMBOL_VALUE (sym) = loc;
+               }
+             add_symbol_to_list (sym, list_in_scope);
+           }
+         break;
+       case TAG_formal_parameter:
+         if (dip->at_location != NULL)
+           {
+             SYMBOL_VALUE (sym) = locval (dip);
+           }
+         add_symbol_to_list (sym, list_in_scope);
+         if (dip->isreg)
+           {
+             SYMBOL_CLASS (sym) = LOC_REGPARM;
+           }
+         else if (dip->offreg)
+           {
+             SYMBOL_CLASS (sym) = LOC_BASEREG_ARG;
+             SYMBOL_BASEREG (sym) = dip->basereg;
+           }
+         else
+           {
+             SYMBOL_CLASS (sym) = LOC_ARG;
+           }
+         break;
+       case TAG_unspecified_parameters:
+         /* From varargs functions; gdb doesn't seem to have any interest in
+            this information, so just ignore it for now. (FIXME?) */
+         break;
+       case TAG_class_type:
+       case TAG_structure_type:
+       case TAG_union_type:
+       case TAG_enumeration_type:
+         SYMBOL_CLASS (sym) = LOC_TYPEDEF;
+         SYMBOL_NAMESPACE (sym) = STRUCT_NAMESPACE;
+         add_symbol_to_list (sym, list_in_scope);
+         break;
+       case TAG_typedef:
+         SYMBOL_CLASS (sym) = LOC_TYPEDEF;
+         SYMBOL_NAMESPACE (sym) = VAR_NAMESPACE;
+         add_symbol_to_list (sym, list_in_scope);
+         break;
+       default:
+         /* Not a tag we recognize.  Hopefully we aren't processing trash
+            data, but since we must specifically ignore things we don't
+            recognize, there is nothing else we should do at this point. */
+         break;
+       }
+    }
+  return (sym);
+}
+
+/*
+
+   LOCAL FUNCTION
+
+   synthesize_typedef -- make a symbol table entry for a "fake" typedef
+
+   SYNOPSIS
+
+   static void synthesize_typedef (struct dieinfo *dip,
+   struct objfile *objfile,
+   struct type *type);
+
+   DESCRIPTION
+
+   Given a pointer to a DWARF information entry, synthesize a typedef
+   for the name in the DIE, using the specified type.
+
+   This is used for C++ class, structs, unions, and enumerations to
+   set up the tag name as a type.
+
+ */
+
+static void
+synthesize_typedef (struct dieinfo *dip, struct objfile *objfile,
+                   struct type *type)
+{
+  struct symbol *sym = NULL;
+
+  if (dip->at_name != NULL)
+    {
+      sym = (struct symbol *)
+       obstack_alloc (&objfile->symbol_obstack, sizeof (struct symbol));
+      OBJSTAT (objfile, n_syms++);
+      memset (sym, 0, sizeof (struct symbol));
+      SYMBOL_NAME (sym) = create_name (dip->at_name,
+                                      &objfile->symbol_obstack);
+      SYMBOL_INIT_LANGUAGE_SPECIFIC (sym, cu_language);
+      SYMBOL_TYPE (sym) = type;
+      SYMBOL_CLASS (sym) = LOC_TYPEDEF;
+      SYMBOL_NAMESPACE (sym) = VAR_NAMESPACE;
+      add_symbol_to_list (sym, list_in_scope);
+    }
+}
+
+/*
+
+   LOCAL FUNCTION
+
+   decode_mod_fund_type -- decode a modified fundamental type
+
+   SYNOPSIS
+
+   static struct type *decode_mod_fund_type (char *typedata)
+
+   DESCRIPTION
+
+   Decode a block of data containing a modified fundamental
+   type specification.  TYPEDATA is a pointer to the block,
+   which starts with a length containing the size of the rest
+   of the block.  At the end of the block is a fundmental type
+   code value that gives the fundamental type.  Everything
+   in between are type modifiers.
+
+   We simply compute the number of modifiers and call the general
+   function decode_modified_type to do the actual work.
+ */
+
+static struct type *
+decode_mod_fund_type (char *typedata)
+{
+  struct type *typep = NULL;
+  unsigned short modcount;
+  int nbytes;
+
+  /* Get the total size of the block, exclusive of the size itself */
+
+  nbytes = attribute_size (AT_mod_fund_type);
+  modcount = target_to_host (typedata, nbytes, GET_UNSIGNED, current_objfile);
+  typedata += nbytes;
+
+  /* Deduct the size of the fundamental type bytes at the end of the block. */
+
+  modcount -= attribute_size (AT_fund_type);
+
+  /* Now do the actual decoding */
+
+  typep = decode_modified_type (typedata, modcount, AT_mod_fund_type);
+  return (typep);
+}
+
+/*
+
+   LOCAL FUNCTION
+
+   decode_mod_u_d_type -- decode a modified user defined type
+
+   SYNOPSIS
+
+   static struct type *decode_mod_u_d_type (char *typedata)
+
+   DESCRIPTION
+
+   Decode a block of data containing a modified user defined
+   type specification.  TYPEDATA is a pointer to the block,
+   which consists of a two byte length, containing the size
+   of the rest of the block.  At the end of the block is a
+   four byte value that gives a reference to a user defined type.
+   Everything in between are type modifiers.
+
+   We simply compute the number of modifiers and call the general
+   function decode_modified_type to do the actual work.
+ */
+
+static struct type *
+decode_mod_u_d_type (char *typedata)
+{
+  struct type *typep = NULL;
+  unsigned short modcount;
+  int nbytes;
+
+  /* Get the total size of the block, exclusive of the size itself */
+
+  nbytes = attribute_size (AT_mod_u_d_type);
+  modcount = target_to_host (typedata, nbytes, GET_UNSIGNED, current_objfile);
+  typedata += nbytes;
+
+  /* Deduct the size of the reference type bytes at the end of the block. */
+
+  modcount -= attribute_size (AT_user_def_type);
+
+  /* Now do the actual decoding */
+
+  typep = decode_modified_type (typedata, modcount, AT_mod_u_d_type);
+  return (typep);
+}
+
+/*
+
+   LOCAL FUNCTION
+
+   decode_modified_type -- decode modified user or fundamental type
+
+   SYNOPSIS
+
+   static struct type *decode_modified_type (char *modifiers,
+   unsigned short modcount, int mtype)
+
+   DESCRIPTION
+
+   Decode a modified type, either a modified fundamental type or
+   a modified user defined type.  MODIFIERS is a pointer to the
+   block of bytes that define MODCOUNT modifiers.  Immediately
+   following the last modifier is a short containing the fundamental
+   type or a long containing the reference to the user defined
+   type.  Which one is determined by MTYPE, which is either
+   AT_mod_fund_type or AT_mod_u_d_type to indicate what modified
+   type we are generating.
+
+   We call ourself recursively to generate each modified type,`
+   until MODCOUNT reaches zero, at which point we have consumed
+   all the modifiers and generate either the fundamental type or
+   user defined type.  When the recursion unwinds, each modifier
+   is applied in turn to generate the full modified type.
+
+   NOTES
+
+   If we find a modifier that we don't recognize, and it is not one
+   of those reserved for application specific use, then we issue a
+   warning and simply ignore the modifier.
+
+   BUGS
+
+   We currently ignore MOD_const and MOD_volatile.  (FIXME)
+
+ */
+
+static struct type *
+decode_modified_type (char *modifiers, unsigned int modcount, int mtype)
+{
+  struct type *typep = NULL;
+  unsigned short fundtype;
+  DIE_REF die_ref;
+  char modifier;
+  int nbytes;
+
+  if (modcount == 0)
+    {
+      switch (mtype)
+       {
+       case AT_mod_fund_type:
+         nbytes = attribute_size (AT_fund_type);
+         fundtype = target_to_host (modifiers, nbytes, GET_UNSIGNED,
+                                    current_objfile);
+         typep = decode_fund_type (fundtype);
+         break;
+       case AT_mod_u_d_type:
+         nbytes = attribute_size (AT_user_def_type);
+         die_ref = target_to_host (modifiers, nbytes, GET_UNSIGNED,
+                                   current_objfile);
+         if ((typep = lookup_utype (die_ref)) == NULL)
+           {
+             typep = alloc_utype (die_ref, NULL);
+           }
+         break;
+       default:
+         complain (&botched_modified_type, DIE_ID, DIE_NAME, mtype);
+         typep = dwarf_fundamental_type (current_objfile, FT_INTEGER);
+         break;
+       }
+    }
+  else
+    {
+      modifier = *modifiers++;
+      typep = decode_modified_type (modifiers, --modcount, mtype);
+      switch (modifier)
+       {
+       case MOD_pointer_to:
+         typep = lookup_pointer_type (typep);
+         break;
+       case MOD_reference_to:
+         typep = lookup_reference_type (typep);
+         break;
+       case MOD_const:
+         complain (&const_ignored, DIE_ID, DIE_NAME);  /* FIXME */
+         break;
+       case MOD_volatile:
+         complain (&volatile_ignored, DIE_ID, DIE_NAME);       /* FIXME */
+         break;
+       default:
+         if (!(MOD_lo_user <= (unsigned char) modifier
+               && (unsigned char) modifier <= MOD_hi_user))
+           {
+             complain (&unknown_type_modifier, DIE_ID, DIE_NAME, modifier);
+           }
+         break;
+       }
+    }
+  return (typep);
+}
+
+/*
+
+   LOCAL FUNCTION
+
+   decode_fund_type -- translate basic DWARF type to gdb base type
+
+   DESCRIPTION
+
+   Given an integer that is one of the fundamental DWARF types,
+   translate it to one of the basic internal gdb types and return
+   a pointer to the appropriate gdb type (a "struct type *").
+
+   NOTES
+
+   For robustness, if we are asked to translate a fundamental
+   type that we are unprepared to deal with, we return int so
+   callers can always depend upon a valid type being returned,
+   and so gdb may at least do something reasonable by default.
+   If the type is not in the range of those types defined as
+   application specific types, we also issue a warning.
+ */
+
+static struct type *
+decode_fund_type (unsigned int fundtype)
+{
+  struct type *typep = NULL;
+
+  switch (fundtype)
+    {
+
+    case FT_void:
+      typep = dwarf_fundamental_type (current_objfile, FT_VOID);
+      break;
+
+    case FT_boolean:           /* Was FT_set in AT&T version */
+      typep = dwarf_fundamental_type (current_objfile, FT_BOOLEAN);
+      break;
+
+    case FT_pointer:           /* (void *) */
+      typep = dwarf_fundamental_type (current_objfile, FT_VOID);
+      typep = lookup_pointer_type (typep);
+      break;
+
+    case FT_char:
+      typep = dwarf_fundamental_type (current_objfile, FT_CHAR);
+      break;
+
+    case FT_signed_char:
+      typep = dwarf_fundamental_type (current_objfile, FT_SIGNED_CHAR);
+      break;
+
+    case FT_unsigned_char:
+      typep = dwarf_fundamental_type (current_objfile, FT_UNSIGNED_CHAR);
+      break;
+
+    case FT_short:
+      typep = dwarf_fundamental_type (current_objfile, FT_SHORT);
+      break;
+
+    case FT_signed_short:
+      typep = dwarf_fundamental_type (current_objfile, FT_SIGNED_SHORT);
+      break;
+
+    case FT_unsigned_short:
+      typep = dwarf_fundamental_type (current_objfile, FT_UNSIGNED_SHORT);
+      break;
+
+    case FT_integer:
+      typep = dwarf_fundamental_type (current_objfile, FT_INTEGER);
+      break;
+
+    case FT_signed_integer:
+      typep = dwarf_fundamental_type (current_objfile, FT_SIGNED_INTEGER);
+      break;
+
+    case FT_unsigned_integer:
+      typep = dwarf_fundamental_type (current_objfile, FT_UNSIGNED_INTEGER);
+      break;
+
+    case FT_long:
+      typep = dwarf_fundamental_type (current_objfile, FT_LONG);
+      break;
+
+    case FT_signed_long:
+      typep = dwarf_fundamental_type (current_objfile, FT_SIGNED_LONG);
+      break;
+
+    case FT_unsigned_long:
+      typep = dwarf_fundamental_type (current_objfile, FT_UNSIGNED_LONG);
+      break;
+
+    case FT_long_long:
+      typep = dwarf_fundamental_type (current_objfile, FT_LONG_LONG);
+      break;
+
+    case FT_signed_long_long:
+      typep = dwarf_fundamental_type (current_objfile, FT_SIGNED_LONG_LONG);
+      break;
+
+    case FT_unsigned_long_long:
+      typep = dwarf_fundamental_type (current_objfile, FT_UNSIGNED_LONG_LONG);
+      break;
+
+    case FT_float:
+      typep = dwarf_fundamental_type (current_objfile, FT_FLOAT);
+      break;
+
+    case FT_dbl_prec_float:
+      typep = dwarf_fundamental_type (current_objfile, FT_DBL_PREC_FLOAT);
+      break;
+
+    case FT_ext_prec_float:
+      typep = dwarf_fundamental_type (current_objfile, FT_EXT_PREC_FLOAT);
+      break;
+
+    case FT_complex:
+      typep = dwarf_fundamental_type (current_objfile, FT_COMPLEX);
+      break;
+
+    case FT_dbl_prec_complex:
+      typep = dwarf_fundamental_type (current_objfile, FT_DBL_PREC_COMPLEX);
+      break;
+
+    case FT_ext_prec_complex:
+      typep = dwarf_fundamental_type (current_objfile, FT_EXT_PREC_COMPLEX);
+      break;
+
+    }
+
+  if (typep == NULL)
+    {
+      typep = dwarf_fundamental_type (current_objfile, FT_INTEGER);
+      if (!(FT_lo_user <= fundtype && fundtype <= FT_hi_user))
+       {
+         complain (&unexpected_fund_type, DIE_ID, DIE_NAME, fundtype);
+       }
+    }
+
+  return (typep);
+}
+
+/*
+
+   LOCAL FUNCTION
+
+   create_name -- allocate a fresh copy of a string on an obstack
+
+   DESCRIPTION
+
+   Given a pointer to a string and a pointer to an obstack, allocates
+   a fresh copy of the string on the specified obstack.
+
+ */
+
+static char *
+create_name (char *name, struct obstack *obstackp)
+{
+  int length;
+  char *newname;
+
+  length = strlen (name) + 1;
+  newname = (char *) obstack_alloc (obstackp, length);
+  strcpy (newname, name);
+  return (newname);
+}
+
+/*
+
+   LOCAL FUNCTION
+
+   basicdieinfo -- extract the minimal die info from raw die data
+
+   SYNOPSIS
+
+   void basicdieinfo (char *diep, struct dieinfo *dip,
+   struct objfile *objfile)
+
+   DESCRIPTION
+
+   Given a pointer to raw DIE data, and a pointer to an instance of a
+   die info structure, this function extracts the basic information
+   from the DIE data required to continue processing this DIE, along
+   with some bookkeeping information about the DIE.
+
+   The information we absolutely must have includes the DIE tag,
+   and the DIE length.  If we need the sibling reference, then we
+   will have to call completedieinfo() to process all the remaining
+   DIE information.
+
+   Note that since there is no guarantee that the data is properly
+   aligned in memory for the type of access required (indirection
+   through anything other than a char pointer), and there is no
+   guarantee that it is in the same byte order as the gdb host,
+   we call a function which deals with both alignment and byte
+   swapping issues.  Possibly inefficient, but quite portable.
+
+   We also take care of some other basic things at this point, such
+   as ensuring that the instance of the die info structure starts
+   out completely zero'd and that curdie is initialized for use
+   in error reporting if we have a problem with the current die.
+
+   NOTES
+
+   All DIE's must have at least a valid length, thus the minimum
+   DIE size is SIZEOF_DIE_LENGTH.  In order to have a valid tag, the
+   DIE size must be at least SIZEOF_DIE_TAG larger, otherwise they
+   are forced to be TAG_padding DIES.
+
+   Padding DIES must be at least SIZEOF_DIE_LENGTH in length, implying
+   that if a padding DIE is used for alignment and the amount needed is
+   less than SIZEOF_DIE_LENGTH, then the padding DIE has to be big
+   enough to align to the next alignment boundry.
+
+   We do some basic sanity checking here, such as verifying that the
+   length of the die would not cause it to overrun the recorded end of
+   the buffer holding the DIE info.  If we find a DIE that is either
+   too small or too large, we force it's length to zero which should
+   cause the caller to take appropriate action.
+ */
+
+static void
+basicdieinfo (struct dieinfo *dip, char *diep, struct objfile *objfile)
+{
+  curdie = dip;
+  memset (dip, 0, sizeof (struct dieinfo));
+  dip->die = diep;
+  dip->die_ref = dbroff + (diep - dbbase);
+  dip->die_length = target_to_host (diep, SIZEOF_DIE_LENGTH, GET_UNSIGNED,
+                                   objfile);
+  if ((dip->die_length < SIZEOF_DIE_LENGTH) ||
+      ((diep + dip->die_length) > (dbbase + dbsize)))
+    {
+      complain (&malformed_die, DIE_ID, DIE_NAME, dip->die_length);
+      dip->die_length = 0;
+    }
+  else if (dip->die_length < (SIZEOF_DIE_LENGTH + SIZEOF_DIE_TAG))
+    {
+      dip->die_tag = TAG_padding;
+    }
+  else
+    {
+      diep += SIZEOF_DIE_LENGTH;
+      dip->die_tag = target_to_host (diep, SIZEOF_DIE_TAG, GET_UNSIGNED,
+                                    objfile);
+    }
+}
+
+/*
+
+   LOCAL FUNCTION
+
+   completedieinfo -- finish reading the information for a given DIE
+
+   SYNOPSIS
+
+   void completedieinfo (struct dieinfo *dip, struct objfile *objfile)
+
+   DESCRIPTION
+
+   Given a pointer to an already partially initialized die info structure,
+   scan the raw DIE data and finish filling in the die info structure
+   from the various attributes found.
+
+   Note that since there is no guarantee that the data is properly
+   aligned in memory for the type of access required (indirection
+   through anything other than a char pointer), and there is no
+   guarantee that it is in the same byte order as the gdb host,
+   we call a function which deals with both alignment and byte
+   swapping issues.  Possibly inefficient, but quite portable.
+
+   NOTES
+
+   Each time we are called, we increment the diecount variable, which
+   keeps an approximate count of the number of dies processed for
+   each compilation unit.  This information is presented to the user
+   if the info_verbose flag is set.
+
+ */
+
+static void
+completedieinfo (struct dieinfo *dip, struct objfile *objfile)
+{
+  char *diep;                  /* Current pointer into raw DIE data */
+  char *end;                   /* Terminate DIE scan here */
+  unsigned short attr;         /* Current attribute being scanned */
+  unsigned short form;         /* Form of the attribute */
+  int nbytes;                  /* Size of next field to read */
+
+  diecount++;
+  diep = dip->die;
+  end = diep + dip->die_length;
+  diep += SIZEOF_DIE_LENGTH + SIZEOF_DIE_TAG;
+  while (diep < end)
+    {
+      attr = target_to_host (diep, SIZEOF_ATTRIBUTE, GET_UNSIGNED, objfile);
+      diep += SIZEOF_ATTRIBUTE;
+      if ((nbytes = attribute_size (attr)) == -1)
+       {
+         complain (&unknown_attribute_length, DIE_ID, DIE_NAME);
+         diep = end;
+         continue;
+       }
+      switch (attr)
+       {
+       case AT_fund_type:
+         dip->at_fund_type = target_to_host (diep, nbytes, GET_UNSIGNED,
+                                             objfile);
+         break;
+       case AT_ordering:
+         dip->at_ordering = target_to_host (diep, nbytes, GET_UNSIGNED,
+                                            objfile);
+         break;
+       case AT_bit_offset:
+         dip->at_bit_offset = target_to_host (diep, nbytes, GET_UNSIGNED,
+                                              objfile);
+         break;
+       case AT_sibling:
+         dip->at_sibling = target_to_host (diep, nbytes, GET_UNSIGNED,
+                                           objfile);
+         break;
+       case AT_stmt_list:
+         dip->at_stmt_list = target_to_host (diep, nbytes, GET_UNSIGNED,
+                                             objfile);
+         dip->has_at_stmt_list = 1;
+         break;
+       case AT_low_pc:
+         dip->at_low_pc = target_to_host (diep, nbytes, GET_UNSIGNED,
+                                          objfile);
+         dip->at_low_pc += baseaddr;
+         dip->has_at_low_pc = 1;
+         break;
+       case AT_high_pc:
+         dip->at_high_pc = target_to_host (diep, nbytes, GET_UNSIGNED,
+                                           objfile);
+         dip->at_high_pc += baseaddr;
+         break;
+       case AT_language:
+         dip->at_language = target_to_host (diep, nbytes, GET_UNSIGNED,
+                                            objfile);
+         break;
+       case AT_user_def_type:
+         dip->at_user_def_type = target_to_host (diep, nbytes,
+                                                 GET_UNSIGNED, objfile);
+         break;
+       case AT_byte_size:
+         dip->at_byte_size = target_to_host (diep, nbytes, GET_UNSIGNED,
+                                             objfile);
+         dip->has_at_byte_size = 1;
+         break;
+       case AT_bit_size:
+         dip->at_bit_size = target_to_host (diep, nbytes, GET_UNSIGNED,
+                                            objfile);
+         break;
+       case AT_member:
+         dip->at_member = target_to_host (diep, nbytes, GET_UNSIGNED,
+                                          objfile);
+         break;
+       case AT_discr:
+         dip->at_discr = target_to_host (diep, nbytes, GET_UNSIGNED,
+                                         objfile);
+         break;
+       case AT_location:
+         dip->at_location = diep;
+         break;
+       case AT_mod_fund_type:
+         dip->at_mod_fund_type = diep;
+         break;
+       case AT_subscr_data:
+         dip->at_subscr_data = diep;
+         break;
+       case AT_mod_u_d_type:
+         dip->at_mod_u_d_type = diep;
+         break;
+       case AT_element_list:
+         dip->at_element_list = diep;
+         dip->short_element_list = 0;
+         break;
+       case AT_short_element_list:
+         dip->at_element_list = diep;
+         dip->short_element_list = 1;
+         break;
+       case AT_discr_value:
+         dip->at_discr_value = diep;
+         break;
+       case AT_string_length:
+         dip->at_string_length = diep;
+         break;
+       case AT_name:
+         dip->at_name = diep;
+         break;
+       case AT_comp_dir:
+         /* For now, ignore any "hostname:" portion, since gdb doesn't
+            know how to deal with it.  (FIXME). */
+         dip->at_comp_dir = strrchr (diep, ':');
+         if (dip->at_comp_dir != NULL)
+           {
+             dip->at_comp_dir++;
+           }
+         else
+           {
+             dip->at_comp_dir = diep;
+           }
+         break;
+       case AT_producer:
+         dip->at_producer = diep;
+         break;
+       case AT_start_scope:
+         dip->at_start_scope = target_to_host (diep, nbytes, GET_UNSIGNED,
+                                               objfile);
+         break;
+       case AT_stride_size:
+         dip->at_stride_size = target_to_host (diep, nbytes, GET_UNSIGNED,
+                                               objfile);
+         break;
+       case AT_src_info:
+         dip->at_src_info = target_to_host (diep, nbytes, GET_UNSIGNED,
+                                            objfile);
+         break;
+       case AT_prototyped:
+         dip->at_prototyped = diep;
+         break;
+       default:
+         /* Found an attribute that we are unprepared to handle.  However
+            it is specifically one of the design goals of DWARF that
+            consumers should ignore unknown attributes.  As long as the
+            form is one that we recognize (so we know how to skip it),
+            we can just ignore the unknown attribute. */
+         break;
+       }
+      form = FORM_FROM_ATTR (attr);
+      switch (form)
+       {
+       case FORM_DATA2:
+         diep += 2;
+         break;
+       case FORM_DATA4:
+       case FORM_REF:
+         diep += 4;
+         break;
+       case FORM_DATA8:
+         diep += 8;
+         break;
+       case FORM_ADDR:
+         diep += TARGET_FT_POINTER_SIZE (objfile);
+         break;
+       case FORM_BLOCK2:
+         diep += 2 + target_to_host (diep, nbytes, GET_UNSIGNED, objfile);
+         break;
+       case FORM_BLOCK4:
+         diep += 4 + target_to_host (diep, nbytes, GET_UNSIGNED, objfile);
+         break;
+       case FORM_STRING:
+         diep += strlen (diep) + 1;
+         break;
+       default:
+         complain (&unknown_attribute_form, DIE_ID, DIE_NAME, form);
+         diep = end;
+         break;
+       }
+    }
+}
+
+/*
+
+   LOCAL FUNCTION
+
+   target_to_host -- swap in target data to host
+
+   SYNOPSIS
+
+   target_to_host (char *from, int nbytes, int signextend,
+   struct objfile *objfile)
+
+   DESCRIPTION
+
+   Given pointer to data in target format in FROM, a byte count for
+   the size of the data in NBYTES, a flag indicating whether or not
+   the data is signed in SIGNEXTEND, and a pointer to the current
+   objfile in OBJFILE, convert the data to host format and return
+   the converted value.
+
+   NOTES
+
+   FIXME:  If we read data that is known to be signed, and expect to
+   use it as signed data, then we need to explicitly sign extend the
+   result until the bfd library is able to do this for us.
+
+   FIXME: Would a 32 bit target ever need an 8 byte result?
+
+ */
+
+static CORE_ADDR
+target_to_host (char *from, int nbytes, int signextend,        /* FIXME:  Unused */
+               struct objfile *objfile)
+{
+  CORE_ADDR rtnval;
+
+  switch (nbytes)
+    {
+    case 8:
+      rtnval = bfd_get_64 (objfile->obfd, (bfd_byte *) from);
+      break;
+    case 4:
+      rtnval = bfd_get_32 (objfile->obfd, (bfd_byte *) from);
+      break;
+    case 2:
+      rtnval = bfd_get_16 (objfile->obfd, (bfd_byte *) from);
+      break;
+    case 1:
+      rtnval = bfd_get_8 (objfile->obfd, (bfd_byte *) from);
+      break;
+    default:
+      complain (&no_bfd_get_N, DIE_ID, DIE_NAME, nbytes);
+      rtnval = 0;
+      break;
+    }
+  return (rtnval);
+}
+
+/*
+
+   LOCAL FUNCTION
+
+   attribute_size -- compute size of data for a DWARF attribute
+
+   SYNOPSIS
+
+   static int attribute_size (unsigned int attr)
+
+   DESCRIPTION
+
+   Given a DWARF attribute in ATTR, compute the size of the first
+   piece of data associated with this attribute and return that
+   size.
+
+   Returns -1 for unrecognized attributes.
+
+ */
+
+static int
+attribute_size (unsigned int attr)
+{
+  int nbytes;                  /* Size of next data for this attribute */
+  unsigned short form;         /* Form of the attribute */
+
+  form = FORM_FROM_ATTR (attr);
+  switch (form)
+    {
+    case FORM_STRING:          /* A variable length field is next */
+      nbytes = 0;
+      break;
+    case FORM_DATA2:           /* Next 2 byte field is the data itself */
+    case FORM_BLOCK2:          /* Next 2 byte field is a block length */
+      nbytes = 2;
+      break;
+    case FORM_DATA4:           /* Next 4 byte field is the data itself */
+    case FORM_BLOCK4:          /* Next 4 byte field is a block length */
+    case FORM_REF:             /* Next 4 byte field is a DIE offset */
+      nbytes = 4;
+      break;
+    case FORM_DATA8:           /* Next 8 byte field is the data itself */
+      nbytes = 8;
+      break;
+    case FORM_ADDR:            /* Next field size is target sizeof(void *) */
+      nbytes = TARGET_FT_POINTER_SIZE (objfile);
+      break;
+    default:
+      complain (&unknown_attribute_form, DIE_ID, DIE_NAME, form);
+      nbytes = -1;
+      break;
+    }
+  return (nbytes);
+}
diff --git a/gdb/hpread.c b/gdb/hpread.c
new file mode 100644 (file)
index 0000000..4cc5f18
--- /dev/null
@@ -0,0 +1,6310 @@
+/* Read hp debug symbols and convert to internal format, for GDB.
+   Copyright 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002
+   Free Software Foundation, Inc.
+
+   This file is part of GDB.
+
+   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.
+
+   Written by the Center for Software Science at the University of Utah
+   and by Cygnus Support.  */
+
+#include "defs.h"
+#include "bfd.h"
+#include "gdb_string.h"
+#include "hp-symtab.h"
+#include "syms.h"
+#include "symtab.h"
+#include "symfile.h"
+#include "objfiles.h"
+#include "buildsym.h"
+#include "complaints.h"
+#include "gdb-stabs.h"
+#include "gdbtypes.h"
+#include "demangle.h"
+
+/* Private information attached to an objfile which we use to find
+   and internalize the HP C debug symbols within that objfile.  */
+
+struct hpread_symfile_info
+  {
+    /* The contents of each of the debug sections (there are 4 of them).  */
+    char *gntt;
+    char *lntt;
+    char *slt;
+    char *vt;
+
+    /* We keep the size of the $VT$ section for range checking.  */
+    unsigned int vt_size;
+
+    /* Some routines still need to know the number of symbols in the
+       main debug sections ($LNTT$ and $GNTT$). */
+    unsigned int lntt_symcount;
+    unsigned int gntt_symcount;
+
+    /* To keep track of all the types we've processed.  */
+    struct type **dntt_type_vector;
+    int dntt_type_vector_length;
+
+    /* Keeps track of the beginning of a range of source lines.  */
+    sltpointer sl_index;
+
+    /* Some state variables we'll need.  */
+    int within_function;
+
+    /* Keep track of the current function's address.  We may need to look
+       up something based on this address.  */
+    unsigned int current_function_value;
+  };
+
+/* Accessor macros to get at the fields.  */
+#define HPUX_SYMFILE_INFO(o) \
+  ((struct hpread_symfile_info *)((o)->sym_private))
+#define GNTT(o)                 (HPUX_SYMFILE_INFO(o)->gntt)
+#define LNTT(o)                 (HPUX_SYMFILE_INFO(o)->lntt)
+#define SLT(o)                  (HPUX_SYMFILE_INFO(o)->slt)
+#define VT(o)                   (HPUX_SYMFILE_INFO(o)->vt)
+#define VT_SIZE(o)              (HPUX_SYMFILE_INFO(o)->vt_size)
+#define LNTT_SYMCOUNT(o)        (HPUX_SYMFILE_INFO(o)->lntt_symcount)
+#define GNTT_SYMCOUNT(o)        (HPUX_SYMFILE_INFO(o)->gntt_symcount)
+#define DNTT_TYPE_VECTOR(o)     (HPUX_SYMFILE_INFO(o)->dntt_type_vector)
+#define DNTT_TYPE_VECTOR_LENGTH(o) \
+  (HPUX_SYMFILE_INFO(o)->dntt_type_vector_length)
+#define SL_INDEX(o)             (HPUX_SYMFILE_INFO(o)->sl_index)
+#define WITHIN_FUNCTION(o)      (HPUX_SYMFILE_INFO(o)->within_function)
+#define CURRENT_FUNCTION_VALUE(o) (HPUX_SYMFILE_INFO(o)->current_function_value)
+
+/* Given the native debug symbol SYM, set NAMEP to the name associated
+   with the debug symbol.  Note we may be called with a debug symbol which
+   has no associated name, in that case we return an empty string.
+
+   Also note we "know" that the name for any symbol is always in the
+   same place.  Hence we don't have to conditionalize on the symbol type.  */
+#define SET_NAMESTRING(SYM, NAMEP, OBJFILE) \
+  if (! hpread_has_name ((SYM)->dblock.kind)) \
+    *NAMEP = ""; \
+  else if (((unsigned)(SYM)->dsfile.name) >= VT_SIZE (OBJFILE)) \
+    { \
+      complain (&string_table_offset_complaint, (char *) symnum); \
+      *NAMEP = ""; \
+    } \
+  else \
+    *NAMEP = (SYM)->dsfile.name + VT (OBJFILE)
+\f
+/* We put a pointer to this structure in the read_symtab_private field
+   of the psymtab.  */
+
+struct symloc
+  {
+    /* The offset within the file symbol table of first local symbol for
+       this file.  */
+
+    int ldsymoff;
+
+    /* Length (in bytes) of the section of the symbol table devoted to
+       this file's symbols (actually, the section bracketed may contain
+       more than just this file's symbols).  If ldsymlen is 0, the only
+       reason for this thing's existence is the dependency list.
+       Nothing else will happen when it is read in.  */
+
+    int ldsymlen;
+  };
+
+#define LDSYMOFF(p) (((struct symloc *)((p)->read_symtab_private))->ldsymoff)
+#define LDSYMLEN(p) (((struct symloc *)((p)->read_symtab_private))->ldsymlen)
+#define SYMLOC(p) ((struct symloc *)((p)->read_symtab_private))
+\f
+/* FIXME: Shouldn't this stuff be in a .h file somewhere?  */
+/* Complaints about the symbols we have encountered.  */
+extern struct complaint string_table_offset_complaint;
+extern struct complaint lbrac_unmatched_complaint;
+extern struct complaint lbrac_mismatch_complaint;
+\f
+static struct complaint hpread_unhandled_end_common_complaint =
+{
+  "unhandled symbol in hp-symtab-read.c: DNTT_TYPE_COMMON/DNTT_TYPE_END.\n", 0, 0
+};
+
+static struct complaint hpread_unhandled_type_complaint =
+{
+  "hpread_type_translate: unhandled type code.", 0, 0
+};
+
+static struct complaint hpread_struct_complaint =
+{
+  "hpread_read_struct_type: expected SVAR type...", 0, 0
+};
+
+static struct complaint hpread_array_complaint =
+{
+  "error in hpread_array_type.", 0, 0
+};
+
+static struct complaint hpread_type_lookup_complaint =
+{
+  "error in hpread_type_lookup().", 0, 0
+};
+
+
+static struct complaint hpread_unexpected_end_complaint =
+{
+  "internal error in hp-symtab-read.c: Unexpected DNTT_TYPE_END kind.", 0, 0
+};
+
+static struct complaint hpread_tagdef_complaint =
+{
+  "error processing class tagdef", 0, 0
+};
+
+static struct complaint hpread_unhandled_common_complaint =
+{
+  "unhandled symbol in hp-symtab-read.c: DNTT_TYPE_COMMON.", 0, 0
+};
+
+static struct complaint hpread_unhandled_blockdata_complaint =
+{
+  "unhandled symbol in hp-symtab-read.c: DNTT_TYPE_BLOCKDATA.", 0, 0
+};
+
+/* To generate dumping code, uncomment this define.  The dumping
+   itself is controlled by routine-local statics called "dumping". */
+/* #define DUMPING         1 */
+
+/* To use the quick look-up tables, uncomment this define. */
+#define QUICK_LOOK_UP      1
+
+/* To call PXDB to process un-processed files, uncomment this define. */
+#define USE_PXDB           1
+
+/* Forward procedure declarations */
+
+void hpread_symfile_init (struct objfile *);
+
+void do_pxdb (bfd *);
+
+void hpread_build_psymtabs (struct objfile *, int);
+
+void hpread_symfile_finish (struct objfile *);
+
+static union dnttentry *hpread_get_gntt (int, struct objfile *);
+
+static union dnttentry *hpread_get_lntt (int index, struct objfile *objfile);
+
+
+static unsigned long hpread_get_textlow (int, int, struct objfile *, int);
+
+static struct partial_symtab *hpread_start_psymtab
+  (struct objfile *, char *, CORE_ADDR, int,
+   struct partial_symbol **, struct partial_symbol **);
+
+static struct partial_symtab *hpread_end_psymtab
+  (struct partial_symtab *, char **, int, int, CORE_ADDR,
+   struct partial_symtab **, int);
+
+static unsigned long hpread_get_scope_start (sltpointer, struct objfile *);
+
+static unsigned long hpread_get_line (sltpointer, struct objfile *);
+
+static CORE_ADDR hpread_get_location (sltpointer, struct objfile *);
+
+static void hpread_psymtab_to_symtab_1 (struct partial_symtab *);
+
+void hpread_psymtab_to_symtab (struct partial_symtab *);
+
+static struct symtab *hpread_expand_symtab
+  (struct objfile *, int, int, CORE_ADDR, int,
+   struct section_offsets *, char *);
+
+static int hpread_type_translate (dnttpointer);
+
+static struct type **hpread_lookup_type (dnttpointer, struct objfile *);
+
+static struct type *hpread_alloc_type (dnttpointer, struct objfile *);
+
+static struct type *hpread_read_enum_type
+  (dnttpointer, union dnttentry *, struct objfile *);
+
+static struct type *hpread_read_function_type
+  (dnttpointer, union dnttentry *, struct objfile *, int);
+
+static struct type *hpread_read_doc_function_type
+  (dnttpointer, union dnttentry *, struct objfile *, int);
+
+static struct type *hpread_read_struct_type
+  (dnttpointer, union dnttentry *, struct objfile *);
+
+static struct type *hpread_get_nth_template_arg (struct objfile *, int);
+
+static struct type *hpread_read_templ_arg_type
+  (dnttpointer, union dnttentry *, struct objfile *, char *);
+
+static struct type *hpread_read_set_type
+  (dnttpointer, union dnttentry *, struct objfile *);
+
+static struct type *hpread_read_array_type
+  (dnttpointer, union dnttentry *dn_bufp, struct objfile *objfile);
+
+static struct type *hpread_read_subrange_type
+  (dnttpointer, union dnttentry *, struct objfile *);
+
+static struct type *hpread_type_lookup (dnttpointer, struct objfile *);
+
+static sltpointer hpread_record_lines
+  (struct subfile *, sltpointer, sltpointer, struct objfile *, CORE_ADDR);
+
+static void hpread_process_one_debug_symbol
+  (union dnttentry *, char *, struct section_offsets *,
+   struct objfile *, CORE_ADDR, int, char *, int, int *);
+
+static int hpread_get_scope_depth (union dnttentry *, struct objfile *, int);
+
+static void fix_static_member_physnames
+  (struct type *, char *, struct objfile *);
+
+static void fixup_class_method_type
+  (struct type *, struct type *, struct objfile *);
+
+static void hpread_adjust_bitoffsets (struct type *, int);
+
+static dnttpointer hpread_get_next_skip_over_anon_unions
+  (int, dnttpointer, union dnttentry **, struct objfile *);
+
+\f
+/* Global to indicate presence of HP-compiled objects,
+   in particular, SOM executable file with SOM debug info 
+   Defined in symtab.c, used in hppa-tdep.c. */
+extern int hp_som_som_object_present;
+
+/* Static used to indicate a class type that requires a
+   fix-up of one of its method types */
+static struct type *fixup_class = NULL;
+
+/* Static used to indicate the method type that is to be
+   used to fix-up the type for fixup_class */
+static struct type *fixup_method = NULL;
+
+#ifdef USE_PXDB
+
+/* NOTE use of system files!  May not be portable. */
+
+#define PXDB_SVR4 "/opt/langtools/bin/pxdb"
+#define PXDB_BSD  "/usr/bin/pxdb"
+
+#include <stdlib.h>
+#include "gdb_string.h"
+
+/* check for the existence of a file, given its full pathname */
+int
+file_exists (char *filename)
+{
+  if (filename)
+    return (access (filename, F_OK) == 0);
+  return 0;
+}
+
+
+/* Translate from the "hp_language" enumeration in hp-symtab.h
+   used in the debug info to gdb's generic enumeration in defs.h. */
+static enum language
+trans_lang (enum hp_language in_lang)
+{
+  if (in_lang == HP_LANGUAGE_C)
+    return language_c;
+
+  else if (in_lang == HP_LANGUAGE_CPLUSPLUS)
+    return language_cplus;
+
+  else if (in_lang == HP_LANGUAGE_FORTRAN)
+    return language_fortran;
+
+  else
+    return language_unknown;
+}
+
+static char main_string[] = "main";
+\f
+/* Call PXDB to process our file.
+
+   Approach copied from DDE's "dbgk_run_pxdb".  Note: we
+   don't check for BSD location of pxdb, nor for existence
+   of pxdb itself, etc.
+
+   NOTE: uses system function and string functions directly.
+
+   Return value: 1 if ok, 0 if not */
+int
+hpread_call_pxdb (const char *file_name)
+{
+  char *p;
+  int status;
+  int retval;
+
+  if (file_exists (PXDB_SVR4))
+    {
+      p = xmalloc (strlen (PXDB_SVR4) + strlen (file_name) + 2);
+      strcpy (p, PXDB_SVR4);
+      strcat (p, " ");
+      strcat (p, file_name);
+
+      warning ("File not processed by pxdb--about to process now.\n");
+      status = system (p);
+
+      retval = (status == 0);
+    }
+  else
+    {
+      warning ("pxdb not found at standard location: /opt/langtools/bin\ngdb will not be able to debug %s.\nPlease install pxdb at the above location and then restart gdb.\nYou can also run pxdb on %s with the command\n\"pxdb %s\" and then restart gdb.", file_name, file_name, file_name);
+
+      retval = 0;
+    }
+  return retval;
+}                              /* hpread_call_pxdb */
+\f
+
+/* Return 1 if the file turns out to need pre-processing
+   by PXDB, and we have thus called PXDB to do this processing
+   and the file therefore needs to be re-loaded.  Otherwise
+   return 0. */
+int
+hpread_pxdb_needed (bfd *sym_bfd)
+{
+  asection *pinfo_section, *debug_section, *header_section;
+  unsigned int do_pxdb;
+  char *buf;
+  bfd_size_type header_section_size;
+
+  unsigned long tmp;
+  unsigned int pxdbed;
+
+  header_section = bfd_get_section_by_name (sym_bfd, "$HEADER$");
+  if (!header_section)
+    {
+      return 0;                        /* No header at all, can't recover... */
+    }
+
+  debug_section = bfd_get_section_by_name (sym_bfd, "$DEBUG$");
+  pinfo_section = bfd_get_section_by_name (sym_bfd, "$PINFO$");
+
+  if (pinfo_section && !debug_section)
+    {
+      /* Debug info with DOC, has different header format. 
+         this only happens if the file was pxdbed and compiled optimized
+         otherwise the PINFO section is not there. */
+      header_section_size = bfd_section_size (objfile->obfd, header_section);
+
+      if (header_section_size == (bfd_size_type) sizeof (DOC_info_PXDB_header))
+       {
+         buf = alloca (sizeof (DOC_info_PXDB_header));
+
+         if (!bfd_get_section_contents (sym_bfd,
+                                        header_section,
+                                        buf, 0,
+                                        header_section_size))
+           error ("bfd_get_section_contents\n");
+
+         tmp = bfd_get_32 (sym_bfd, (bfd_byte *) (buf + sizeof (int) * 4));
+         pxdbed = (tmp >> 31) & 0x1;
+
+         if (!pxdbed)
+           error ("file debug header info invalid\n");
+         do_pxdb = 0;
+       }
+
+      else
+       error ("invalid $HEADER$ size in executable \n");
+    }
+
+  else
+    {
+
+      /* this can be three different cases:
+         1. pxdbed and not doc
+         - DEBUG and HEADER sections are there
+         - header is PXDB_header type
+         - pxdbed flag is set to 1
+
+         2. not pxdbed and doc
+         - DEBUG and HEADER  sections are there
+         - header is DOC_info_header type
+         - pxdbed flag is set to 0
+
+         3. not pxdbed and not doc
+         - DEBUG and HEADER sections are there
+         - header is XDB_header type
+         - pxdbed flag is set to 0
+
+         NOTE: the pxdbed flag is meaningful also in the not
+         already pxdb processed version of the header,
+         because in case on non-already processed by pxdb files
+         that same bit in the header would be always zero.
+         Why? Because the bit is the leftmost bit of a word
+         which contains a 'length' which is always a positive value
+         so that bit is never set to 1 (otherwise it would be negative)
+
+         Given the above, we have two choices : either we ignore the
+         size of the header itself and just look at the pxdbed field,
+         or we check the size and then we (for safety and paranoia related
+         issues) check the bit.
+         The first solution is used by DDE, the second by PXDB itself.
+         I am using the second one here, because I already wrote it,
+         and it is the end of a long day.
+         Also, using the first approach would still involve size issues
+         because we need to read in the contents of the header section, and
+         give the correct amount of stuff we want to read to the
+         get_bfd_section_contents function.  */
+
+      /* decide which case depending on the size of the header section.
+         The size is as defined in hp-symtab.h  */
+
+      header_section_size = bfd_section_size (objfile->obfd, header_section);
+
+      if (header_section_size == (bfd_size_type) sizeof (PXDB_header)) /* pxdb and not doc */
+       {
+
+         buf = alloca (sizeof (PXDB_header));
+         if (!bfd_get_section_contents (sym_bfd,
+                                        header_section,
+                                        buf, 0,
+                                        header_section_size))
+           error ("bfd_get_section_contents\n");
+
+         tmp = bfd_get_32 (sym_bfd, (bfd_byte *) (buf + sizeof (int) * 3));
+         pxdbed = (tmp >> 31) & 0x1;
+
+         if (pxdbed)
+           do_pxdb = 0;
+         else
+           error ("file debug header invalid\n");
+       }
+      else                     /*not pxdbed and doc OR not pxdbed and non doc */
+       do_pxdb = 1;
+    }
+
+  if (do_pxdb)
+    {
+      return 1;
+    }
+  else
+    {
+      return 0;
+    }
+}                              /* hpread_pxdb_needed */
+
+#endif
+
+/* Check whether the file needs to be preprocessed by pxdb. 
+   If so, call pxdb. */
+
+void
+do_pxdb (bfd *sym_bfd)
+{
+  /* The following code is HP-specific.  The "right" way of
+     doing this is unknown, but we bet would involve a target-
+     specific pre-file-load check using a generic mechanism. */
+
+  /* This code will not be executed if the file is not in SOM
+     format (i.e. if compiled with gcc) */
+  if (hpread_pxdb_needed (sym_bfd))
+    {
+      /*This file has not been pre-processed. Preprocess now */
+
+      if (hpread_call_pxdb (sym_bfd->filename))
+       {
+         /* The call above has changed the on-disk file, 
+            we can close the file anyway, because the
+            symbols will be reread in when the target is run */
+         bfd_close (sym_bfd);
+       }
+    }
+}
+\f
+
+
+#ifdef QUICK_LOOK_UP
+
+/* Code to handle quick lookup-tables follows. */
+
+
+/* Some useful macros */
+#define VALID_FILE(i)   ((i) < pxdb_header_p->fd_entries)
+#define VALID_MODULE(i) ((i) < pxdb_header_p->md_entries)
+#define VALID_PROC(i)   ((i) < pxdb_header_p->pd_entries)
+#define VALID_CLASS(i)  ((i) < pxdb_header_p->cd_entries)
+
+#define FILE_START(i)    (qFD[i].adrStart)
+#define MODULE_START(i) (qMD[i].adrStart)
+#define PROC_START(i)    (qPD[i].adrStart)
+
+#define FILE_END(i)   (qFD[i].adrEnd)
+#define MODULE_END(i) (qMD[i].adrEnd)
+#define PROC_END(i)   (qPD[i].adrEnd)
+
+#define FILE_ISYM(i)   (qFD[i].isym)
+#define MODULE_ISYM(i) (qMD[i].isym)
+#define PROC_ISYM(i)   (qPD[i].isym)
+
+#define VALID_CURR_FILE    (curr_fd < pxdb_header_p->fd_entries)
+#define VALID_CURR_MODULE  (curr_md < pxdb_header_p->md_entries)
+#define VALID_CURR_PROC    (curr_pd < pxdb_header_p->pd_entries)
+#define VALID_CURR_CLASS   (curr_cd < pxdb_header_p->cd_entries)
+
+#define CURR_FILE_START     (qFD[curr_fd].adrStart)
+#define CURR_MODULE_START   (qMD[curr_md].adrStart)
+#define CURR_PROC_START     (qPD[curr_pd].adrStart)
+
+#define CURR_FILE_END    (qFD[curr_fd].adrEnd)
+#define CURR_MODULE_END  (qMD[curr_md].adrEnd)
+#define CURR_PROC_END    (qPD[curr_pd].adrEnd)
+
+#define CURR_FILE_ISYM    (qFD[curr_fd].isym)
+#define CURR_MODULE_ISYM  (qMD[curr_md].isym)
+#define CURR_PROC_ISYM    (qPD[curr_pd].isym)
+
+#define TELL_OBJFILE                                      \
+            do {                                          \
+               if( !told_objfile ) {                      \
+                   told_objfile = 1;                      \
+                   warning ("\nIn object file \"%s\":\n", \
+                            objfile->name);               \
+               }                                          \
+            } while (0)
+\f
+
+
+/* Keeping track of the start/end symbol table (LNTT) indices of
+   psymtabs created so far */
+
+typedef struct
+{
+  int start;
+  int end;
+}
+pst_syms_struct;
+
+static pst_syms_struct *pst_syms_array = 0;
+
+static pst_syms_count = 0;
+static pst_syms_size = 0;
+
+/* used by the TELL_OBJFILE macro */
+static boolean told_objfile = 0;
+
+/* Set up psymtab symbol index stuff */
+static void
+init_pst_syms (void)
+{
+  pst_syms_count = 0;
+  pst_syms_size = 20;
+  pst_syms_array = (pst_syms_struct *) xmalloc (20 * sizeof (pst_syms_struct));
+}
+
+/* Clean up psymtab symbol index stuff */
+static void
+clear_pst_syms (void)
+{
+  pst_syms_count = 0;
+  pst_syms_size = 0;
+  xfree (pst_syms_array);
+  pst_syms_array = 0;
+}
+
+/* Add information about latest psymtab to symbol index table */
+static void
+record_pst_syms (int start_sym, int end_sym)
+{
+  if (++pst_syms_count > pst_syms_size)
+    {
+      pst_syms_array = (pst_syms_struct *) xrealloc (pst_syms_array,
+                             2 * pst_syms_size * sizeof (pst_syms_struct));
+      pst_syms_size *= 2;
+    }
+  pst_syms_array[pst_syms_count - 1].start = start_sym;
+  pst_syms_array[pst_syms_count - 1].end = end_sym;
+}
+
+/* Find a suitable symbol table index which can serve as the upper
+   bound of a psymtab that starts at INDEX
+
+   This scans backwards in the psymtab symbol index table to find a
+   "hole" in which the given index can fit.  This is a heuristic!!
+   We don't search the entire table to check for multiple holes,
+   we don't care about overlaps, etc. 
+
+   Return 0 => not found */
+static int
+find_next_pst_start (int index)
+{
+  int i;
+
+  for (i = pst_syms_count - 1; i >= 0; i--)
+    if (pst_syms_array[i].end <= index)
+      return (i == pst_syms_count - 1) ? 0 : pst_syms_array[i + 1].start - 1;
+
+  if (pst_syms_array[0].start > index)
+    return pst_syms_array[0].start - 1;
+
+  return 0;
+}
+\f
+
+
+/* Utility functions to find the ending symbol index for a psymtab */
+
+/* Find the next file entry that begins beyond INDEX, and return
+   its starting symbol index - 1.
+   QFD is the file table, CURR_FD is the file entry from where to start,
+   PXDB_HEADER_P as in hpread_quick_traverse (to allow macros to work).
+
+   Return 0 => not found */
+static int
+find_next_file_isym (int index, quick_file_entry *qFD, int curr_fd,
+                    PXDB_header_ptr pxdb_header_p)
+{
+  while (VALID_CURR_FILE)
+    {
+      if (CURR_FILE_ISYM >= index)
+       return CURR_FILE_ISYM - 1;
+      curr_fd++;
+    }
+  return 0;
+}
+
+/* Find the next procedure entry that begins beyond INDEX, and return
+   its starting symbol index - 1.
+   QPD is the procedure table, CURR_PD is the proc entry from where to start,
+   PXDB_HEADER_P as in hpread_quick_traverse (to allow macros to work).
+
+   Return 0 => not found */
+static int
+find_next_proc_isym (int index, quick_procedure_entry *qPD, int curr_pd,
+                    PXDB_header_ptr pxdb_header_p)
+{
+  while (VALID_CURR_PROC)
+    {
+      if (CURR_PROC_ISYM >= index)
+       return CURR_PROC_ISYM - 1;
+      curr_pd++;
+    }
+  return 0;
+}
+
+/* Find the next module entry that begins beyond INDEX, and return
+   its starting symbol index - 1.
+   QMD is the module table, CURR_MD is the modue entry from where to start,
+   PXDB_HEADER_P as in hpread_quick_traverse (to allow macros to work).
+
+   Return 0 => not found */
+static int
+find_next_module_isym (int index, quick_module_entry *qMD, int curr_md,
+                      PXDB_header_ptr pxdb_header_p)
+{
+  while (VALID_CURR_MODULE)
+    {
+      if (CURR_MODULE_ISYM >= index)
+       return CURR_MODULE_ISYM - 1;
+      curr_md++;
+    }
+  return 0;
+}
+
+/* Scan and record partial symbols for all functions starting from index
+   pointed to by CURR_PD_P, and between code addresses START_ADR and END_ADR.
+   Other parameters are explained in comments below. */
+
+/* This used to be inline in hpread_quick_traverse, but now that we do
+   essentially the same thing for two different cases (modules and
+   module-less files), it's better organized in a separate routine,
+   although it does take lots of arguments.  pai/1997-10-08
+   
+   CURR_PD_P is the pointer to the current proc index. QPD is the
+   procedure quick lookup table.  MAX_PROCS is the number of entries
+   in the proc. table.  START_ADR is the beginning of the code range
+   for the current psymtab.  end_adr is the end of the code range for
+   the current psymtab.  PST is the current psymtab.  VT_bits is
+   a pointer to the strings table of SOM debug space.  OBJFILE is
+   the current object file. */
+
+static int
+scan_procs (int *curr_pd_p, quick_procedure_entry *qPD, int max_procs,
+           CORE_ADDR start_adr, CORE_ADDR end_adr, struct partial_symtab *pst,
+           char *vt_bits, struct objfile *objfile)
+{
+  union dnttentry *dn_bufp;
+  int symbol_count = 0;                /* Total number of symbols in this psymtab */
+  int curr_pd = *curr_pd_p;    /* Convenience variable -- avoid dereferencing pointer all the time */
+
+#ifdef DUMPING
+  /* Turn this on for lots of debugging information in this routine */
+  static int dumping = 0;
+#endif
+
+#ifdef DUMPING
+  if (dumping)
+    {
+      printf ("Scan_procs called, addresses %x to %x, proc %x\n", start_adr, end_adr, curr_pd);
+    }
+#endif
+
+  while ((CURR_PROC_START <= end_adr) && (curr_pd < max_procs))
+    {
+
+      char *rtn_name;          /* mangled name */
+      char *rtn_dem_name;      /* qualified demangled name */
+      char *class_name;
+      int class;
+
+      if ((trans_lang ((enum hp_language) qPD[curr_pd].language) == language_cplus) &&
+         vt_bits[(long) qPD[curr_pd].sbAlias])         /* not a null string */
+       {
+         /* Get mangled name for the procedure, and demangle it */
+         rtn_name = &vt_bits[(long) qPD[curr_pd].sbAlias];
+         rtn_dem_name = cplus_demangle (rtn_name, DMGL_ANSI | DMGL_PARAMS);
+       }
+      else
+       {
+         rtn_name = &vt_bits[(long) qPD[curr_pd].sbProc];
+         rtn_dem_name = NULL;
+       }
+
+      /* Hack to get around HP C/C++ compilers' insistence on providing
+         "_MAIN_" as an alternate name for "main" */
+      if ((strcmp (rtn_name, "_MAIN_") == 0) &&
+         (strcmp (&vt_bits[(long) qPD[curr_pd].sbProc], "main") == 0))
+       rtn_dem_name = rtn_name = main_string;
+
+#ifdef DUMPING
+      if (dumping)
+       {
+         printf ("..add %s (demangled %s), index %x to this psymtab\n", rtn_name, rtn_dem_name, curr_pd);
+       }
+#endif
+
+      /* Check for module-spanning routines. */
+      if (CURR_PROC_END > end_adr)
+       {
+         TELL_OBJFILE;
+         warning ("Procedure \"%s\" [0x%x] spans file or module boundaries.", rtn_name, curr_pd);
+       }
+
+      /* Add this routine symbol to the list in the objfile. 
+         Unfortunately we have to go to the LNTT to determine the
+         correct list to put it on. An alternative (which the
+         code used to do) would be to not check and always throw
+         it on the "static" list. But if we go that route, then
+         symbol_lookup() needs to be tweaked a bit to account
+         for the fact that the function might not be found on
+         the correct list in the psymtab. - RT */
+      dn_bufp = hpread_get_lntt (qPD[curr_pd].isym, objfile);
+      if (dn_bufp->dfunc.global)
+       add_psymbol_with_dem_name_to_list (rtn_name,
+                                          strlen (rtn_name),
+                                          rtn_dem_name,
+                                          strlen (rtn_dem_name),
+                                          VAR_NAMESPACE,
+                                          LOC_BLOCK,   /* "I am a routine"        */
+                                          &objfile->global_psymbols,
+                                          (qPD[curr_pd].adrStart +     /* Starting address of rtn */
+                                ANOFFSET (objfile->section_offsets, SECT_OFF_TEXT (objfile))),
+                                          0,   /* core addr?? */
+                     trans_lang ((enum hp_language) qPD[curr_pd].language),
+                                          objfile);
+      else
+       add_psymbol_with_dem_name_to_list (rtn_name,
+                                          strlen (rtn_name),
+                                          rtn_dem_name,
+                                          strlen (rtn_dem_name),
+                                          VAR_NAMESPACE,
+                                          LOC_BLOCK,   /* "I am a routine"        */
+                                          &objfile->static_psymbols,
+                                          (qPD[curr_pd].adrStart +     /* Starting address of rtn */
+                                ANOFFSET (objfile->section_offsets, SECT_OFF_TEXT (objfile))),
+                                          0,   /* core addr?? */
+                     trans_lang ((enum hp_language) qPD[curr_pd].language),
+                                          objfile);
+
+      symbol_count++;
+      *curr_pd_p = ++curr_pd;  /* bump up count & reflect in caller */
+    }                          /* loop over procedures */
+
+#ifdef DUMPING
+  if (dumping)
+    {
+      if (symbol_count == 0)
+       printf ("Scan_procs: no symbols found!\n");
+    }
+#endif
+
+  return symbol_count;
+}
+
+
+/* Traverse the quick look-up tables, building a set of psymtabs.
+
+   This constructs a psymtab for modules and files in the quick lookup
+   tables.
+
+   Mostly, modules correspond to compilation units, so we try to
+   create psymtabs that correspond to modules; however, in some cases
+   a file can result in a compiled object which does not have a module
+   entry for it, so in such cases we create a psymtab for the file.  */
+
+int
+hpread_quick_traverse (struct objfile *objfile, char *gntt_bits,
+                      char *vt_bits, PXDB_header_ptr pxdb_header_p)
+{
+  struct partial_symtab *pst;
+
+  char *addr;
+
+  quick_procedure_entry *qPD;
+  quick_file_entry *qFD;
+  quick_module_entry *qMD;
+  quick_class_entry *qCD;
+
+  int idx;
+  int i;
+  CORE_ADDR start_adr;         /* current psymtab's starting code addr   */
+  CORE_ADDR end_adr;           /* current psymtab's ending code addr     */
+  CORE_ADDR next_mod_adr;      /* next module's starting code addr    */
+  int curr_pd;                 /* current procedure */
+  int curr_fd;                 /* current file      */
+  int curr_md;                 /* current module    */
+  int start_sym;               /* current psymtab's starting symbol index */
+  int end_sym;                 /* current psymtab's ending symbol index   */
+  int max_LNTT_sym_index;
+  int syms_in_pst;
+  B_TYPE *class_entered;
+
+  struct partial_symbol **global_syms; /* We'll be filling in the "global"   */
+  struct partial_symbol **static_syms; /* and "static" tables in the objfile
+                                          as we go, so we need a pair of     
+                                          current pointers. */
+
+#ifdef DUMPING
+  /* Turn this on for lots of debugging information in this routine.
+     You get a blow-by-blow account of quick lookup table reading */
+  static int dumping = 0;
+#endif
+
+  pst = (struct partial_symtab *) 0;
+
+  /* Clear out some globals */
+  init_pst_syms ();
+  told_objfile = 0;
+
+  /* Demangling style -- if EDG style already set, don't change it,
+     as HP style causes some problems with the KAI EDG compiler */
+  if (current_demangling_style != edg_demangling)
+    {
+      /* Otherwise, ensure that we are using HP style demangling */
+      set_demangling_style (HP_DEMANGLING_STYLE_STRING);
+    }
+
+  /* First we need to find the starting points of the quick
+     look-up tables in the GNTT. */
+
+  addr = gntt_bits;
+
+  qPD = (quick_procedure_entry_ptr) addr;
+  addr += pxdb_header_p->pd_entries * sizeof (quick_procedure_entry);
+
+#ifdef DUMPING
+  if (dumping)
+    {
+      printf ("\n Printing routines as we see them\n");
+      for (i = 0; VALID_PROC (i); i++)
+       {
+         idx = (long) qPD[i].sbProc;
+         printf ("%s %x..%x\n", &vt_bits[idx],
+                 (int) PROC_START (i),
+                 (int) PROC_END (i));
+       }
+    }
+#endif
+
+  qFD = (quick_file_entry_ptr) addr;
+  addr += pxdb_header_p->fd_entries * sizeof (quick_file_entry);
+
+#ifdef DUMPING
+  if (dumping)
+    {
+      printf ("\n Printing files as we see them\n");
+      for (i = 0; VALID_FILE (i); i++)
+       {
+         idx = (long) qFD[i].sbFile;
+         printf ("%s %x..%x\n", &vt_bits[idx],
+                 (int) FILE_START (i),
+                 (int) FILE_END (i));
+       }
+    }
+#endif
+
+  qMD = (quick_module_entry_ptr) addr;
+  addr += pxdb_header_p->md_entries * sizeof (quick_module_entry);
+
+#ifdef DUMPING
+  if (dumping)
+    {
+      printf ("\n Printing modules as we see them\n");
+      for (i = 0; i < pxdb_header_p->md_entries; i++)
+       {
+         idx = (long) qMD[i].sbMod;
+         printf ("%s\n", &vt_bits[idx]);
+       }
+    }
+#endif
+
+  qCD = (quick_class_entry_ptr) addr;
+  addr += pxdb_header_p->cd_entries * sizeof (quick_class_entry);
+
+#ifdef DUMPING
+  if (dumping)
+    {
+      printf ("\n Printing classes as we see them\n");
+      for (i = 0; VALID_CLASS (i); i++)
+       {
+         idx = (long) qCD[i].sbClass;
+         printf ("%s\n", &vt_bits[idx]);
+       }
+
+      printf ("\n Done with dump, on to build!\n");
+    }
+#endif
+
+  /* We need this index only while hp-symtab-read.c expects
+     a byte offset to the end of the LNTT entries for a given
+     psymtab.  Thus the need for it should go away someday.
+
+     When it goes away, then we won't have any need to load the
+     LNTT from the objfile at psymtab-time, and start-up will be
+     faster.  To make that work, we'll need some way to create
+     a null pst for the "globals" pseudo-module. */
+  max_LNTT_sym_index = LNTT_SYMCOUNT (objfile);
+
+  /* Scan the module descriptors and make a psymtab for each.
+
+     We know the MDs, FDs and the PDs are in order by starting
+     address.  We use that fact to traverse all three arrays in
+     parallel, knowing when the next PD is in a new file
+     and we need to create a new psymtab. */
+  curr_pd = 0;                 /* Current procedure entry */
+  curr_fd = 0;                 /* Current file entry */
+  curr_md = 0;                 /* Current module entry */
+
+  start_adr = 0;               /* Current psymtab code range */
+  end_adr = 0;
+
+  start_sym = 0;               /* Current psymtab symbol range */
+  end_sym = 0;
+
+  syms_in_pst = 0;             /* Symbol count for psymtab */
+
+  /* Psts actually just have pointers into the objfile's
+     symbol table, not their own symbol tables. */
+  global_syms = objfile->global_psymbols.list;
+  static_syms = objfile->static_psymbols.list;
+
+
+  /* First skip over pseudo-entries with address 0.  These represent inlined
+     routines and abstract (uninstantiated) template routines.
+     FIXME: These should be read in and available -- even if we can't set
+     breakpoints, etc., there's some information that can be presented
+     to the user. pai/1997-10-08  */
+
+  while (VALID_CURR_PROC && (CURR_PROC_START == 0))
+    curr_pd++;
+
+  /* Loop over files, modules, and procedures in code address order. Each
+     time we enter an iteration of this loop, curr_pd points to the first
+     unprocessed procedure, curr_fd points to the first unprocessed file, and
+     curr_md to the first unprocessed module.  Each iteration of this loop
+     updates these as required -- any or all of them may be bumpd up
+     each time around.  When we exit this loop, we are done with all files
+     and modules in the tables -- there may still be some procedures, however.
+
+     Note: This code used to loop only over module entries, under the assumption
+     that files can occur via inclusions and are thus unreliable, while a
+     compiled object always corresponds to a module.  With CTTI in the HP aCC
+     compiler, it turns out that compiled objects may have only files and no
+     modules; so we have to loop over files and modules, creating psymtabs for
+     either as appropriate.  Unfortunately there are some problems (notably:
+     1. the lack of "SRC_FILE_END" entries in the LNTT, 2. the lack of pointers
+     to the ending symbol indices of a module or a file) which make it quite hard
+     to do this correctly.  Currently it uses a bunch of heuristics to start and
+     end psymtabs; they seem to work well with most objects generated by aCC, but
+     who knows when that will change...   */
+
+  while (VALID_CURR_FILE || VALID_CURR_MODULE)
+    {
+
+      char *mod_name_string;
+      char *full_name_string;
+
+      /* First check for modules like "version.c", which have no code
+         in them but still have qMD entries.  They also have no qFD or
+         qPD entries.  Their start address is -1 and their end address
+         is 0.  */
+      if (VALID_CURR_MODULE && (CURR_MODULE_START == -1) && (CURR_MODULE_END == 0))
+       {
+
+         mod_name_string = &vt_bits[(long) qMD[curr_md].sbMod];
+
+#ifdef DUMPING
+         if (dumping)
+           printf ("Module with data only %s\n", mod_name_string);
+#endif
+
+         /* We'll skip the rest (it makes error-checking easier), and
+            just make an empty pst.  Right now empty psts are not put
+            in the pst chain, so all this is for naught, but later it
+            might help.  */
+
+         pst = hpread_start_psymtab (objfile,
+                                     mod_name_string,
+                                     CURR_MODULE_START,        /* Low text address: bogus! */
+                      (CURR_MODULE_ISYM * sizeof (struct dntt_type_block)),
+         /* ldsymoff */
+                                     global_syms,
+                                     static_syms);
+
+         pst = hpread_end_psymtab (pst,
+                                   NULL,       /* psymtab_include_list */
+                                   0,  /* includes_used        */
+                                 end_sym * sizeof (struct dntt_type_block),
+         /* byte index in LNTT of end 
+            = capping symbol offset  
+            = LDSYMOFF of nextfile */
+                                   0,  /* text high            */
+                                   NULL,       /* dependency_list      */
+                                   0);         /* dependencies_used    */
+
+         global_syms = objfile->global_psymbols.next;
+         static_syms = objfile->static_psymbols.next;
+
+         curr_md++;
+       }
+      else if (VALID_CURR_MODULE &&
+              ((CURR_MODULE_START == 0) || (CURR_MODULE_START == -1) ||
+               (CURR_MODULE_END == 0) || (CURR_MODULE_END == -1)))
+       {
+         TELL_OBJFILE;
+         warning ("Module \"%s\" [0x%s] has non-standard addresses.  It starts at 0x%s, ends at 0x%s, and will be skipped.",
+                  mod_name_string, paddr_nz (curr_md), paddr_nz (start_adr), paddr_nz (end_adr));
+         /* On to next module */
+         curr_md++;
+       }
+      else
+       {
+         /* First check if we are looking at a file with code in it
+            that does not overlap the current module's code range */
+
+         if (VALID_CURR_FILE ? (VALID_CURR_MODULE ? (CURR_FILE_END < CURR_MODULE_START) : 1) : 0)
+           {
+
+             /* Looking at file not corresponding to any module,
+                create a psymtab for it */
+             full_name_string = &vt_bits[(long) qFD[curr_fd].sbFile];
+             start_adr = CURR_FILE_START;
+             end_adr = CURR_FILE_END;
+             start_sym = CURR_FILE_ISYM;
+
+             /* Check if there are any procedures not handled until now, that
+                begin before the start address of this file, and if so, adjust
+                this module's start address to include them.  This handles routines that
+                are in between file or module ranges for some reason (probably
+                indicates a compiler bug */
+
+             if (CURR_PROC_START < start_adr)
+               {
+                 TELL_OBJFILE;
+                 warning ("Found procedure \"%s\" [0x%x] that is not in any file or module.",
+                          &vt_bits[(long) qPD[curr_pd].sbProc], curr_pd);
+                 start_adr = CURR_PROC_START;
+                 if (CURR_PROC_ISYM < start_sym)
+                   start_sym = CURR_PROC_ISYM;
+               }
+
+             /* Sometimes (compiler bug -- COBOL) the module end address is higher
+                than the start address of the next module, so check for that and
+                adjust accordingly */
+
+             if (VALID_FILE (curr_fd + 1) && (FILE_START (curr_fd + 1) <= end_adr))
+               {
+                 TELL_OBJFILE;
+                 warning ("File \"%s\" [0x%x] has ending address after starting address of next file; adjusting ending address down.",
+                          full_name_string, curr_fd);
+                 end_adr = FILE_START (curr_fd + 1) - 1;       /* Is -4 (or -8 for 64-bit) better? */
+               }
+             if (VALID_MODULE (curr_md) && (CURR_MODULE_START <= end_adr))
+               {
+                 TELL_OBJFILE;
+                 warning ("File \"%s\" [0x%x] has ending address after starting address of next module; adjusting ending address down.",
+                          full_name_string, curr_fd);
+                 end_adr = CURR_MODULE_START - 1;      /* Is -4 (or -8 for 64-bit) better? */
+               }
+
+
+#ifdef DUMPING
+             if (dumping)
+               {
+                 printf ("Make new psymtab for file %s (%x to %x).\n",
+                         full_name_string, start_adr, end_adr);
+               }
+#endif
+             /* Create the basic psymtab, connecting it in the list
+                for this objfile and pointing its symbol entries
+                to the current end of the symbol areas in the objfile.
+
+                The "ldsymoff" parameter is the byte offset in the LNTT
+                of the first symbol in this file.  Some day we should
+                turn this into an index (fix in hp-symtab-read.c as well).
+                And it's not even the right byte offset, as we're using
+                the size of a union! FIXME!  */
+             pst = hpread_start_psymtab (objfile,
+                                         full_name_string,
+                                         start_adr,    /* Low text address */
+                             (start_sym * sizeof (struct dntt_type_block)),
+             /* ldsymoff */
+                                         global_syms,
+                                         static_syms);
+
+             /* Set up to only enter each class referenced in this module once.  */
+             class_entered = xmalloc (B_BYTES (pxdb_header_p->cd_entries));
+             B_CLRALL (class_entered, pxdb_header_p->cd_entries);
+
+             /* Scan the procedure descriptors for procedures in the current
+                file, based on the starting addresses. */
+
+             syms_in_pst = scan_procs (&curr_pd, qPD, pxdb_header_p->pd_entries,
+                                       start_adr, end_adr, pst, vt_bits, objfile);
+
+             /* Get ending symbol offset */
+
+             end_sym = 0;
+             /* First check for starting index before previous psymtab */
+             if (pst_syms_count && start_sym < pst_syms_array[pst_syms_count - 1].end)
+               {
+                 end_sym = find_next_pst_start (start_sym);
+               }
+             /* Look for next start index of a file or module, or procedure */
+             if (!end_sym)
+               {
+                 int next_file_isym = find_next_file_isym (start_sym, qFD, curr_fd + 1, pxdb_header_p);
+                 int next_module_isym = find_next_module_isym (start_sym, qMD, curr_md, pxdb_header_p);
+                 int next_proc_isym = find_next_proc_isym (start_sym, qPD, curr_pd, pxdb_header_p);
+
+                 if (next_file_isym && next_module_isym)
+                   {
+                     /* pick lower of next file or module start index */
+                     end_sym = min (next_file_isym, next_module_isym);
+                   }
+                 else
+                   {
+                     /* one of them is zero, pick the other */
+                     end_sym = max (next_file_isym, next_module_isym);
+                   }
+
+                 /* As a precaution, check next procedure index too */
+                 if (!end_sym)
+                   end_sym = next_proc_isym;
+                 else
+                   end_sym = min (end_sym, next_proc_isym);
+               }
+
+             /* Couldn't find procedure, file, or module, use globals as default */
+             if (!end_sym)
+               end_sym = pxdb_header_p->globals;
+
+#ifdef DUMPING
+             if (dumping)
+               {
+                 printf ("File psymtab indices: %x to %x\n", start_sym, end_sym);
+               }
+#endif
+
+             pst = hpread_end_psymtab (pst,
+                                       NULL,   /* psymtab_include_list */
+                                       0,      /* includes_used        */
+                                 end_sym * sizeof (struct dntt_type_block),
+             /* byte index in LNTT of end 
+                = capping symbol offset   
+                = LDSYMOFF of nextfile */
+                                       end_adr,        /* text high */
+                                       NULL,   /* dependency_list */
+                                       0);     /* dependencies_used */
+
+             record_pst_syms (start_sym, end_sym);
+
+             if (NULL == pst)
+               warning ("No symbols in psymtab for file \"%s\" [0x%x].", full_name_string, curr_fd);
+
+#ifdef DUMPING
+             if (dumping)
+               {
+                 printf ("Made new psymtab for file %s (%x to %x), sym %x to %x.\n",
+                         full_name_string, start_adr, end_adr, CURR_FILE_ISYM, end_sym);
+               }
+#endif
+             /* Prepare for the next psymtab. */
+             global_syms = objfile->global_psymbols.next;
+             static_syms = objfile->static_psymbols.next;
+             xfree (class_entered);
+
+             curr_fd++;
+           }                   /* Psymtab for file */
+         else
+           {
+             /* We have a module for which we create a psymtab */
+
+             mod_name_string = &vt_bits[(long) qMD[curr_md].sbMod];
+
+             /* We will include the code ranges of any files that happen to
+                overlap with this module */
+
+             /* So, first pick the lower of the file's and module's start addresses */
+             start_adr = CURR_MODULE_START;
+             if (VALID_CURR_FILE)
+               {
+                 if (CURR_FILE_START < CURR_MODULE_START)
+                   {
+                     TELL_OBJFILE;
+                     warning ("File \"%s\" [0x%x] crosses beginning of module \"%s\".",
+                              &vt_bits[(long) qFD[curr_fd].sbFile],
+                              curr_fd, mod_name_string);
+
+                     start_adr = CURR_FILE_START;
+                   }
+               }
+
+             /* Also pick the lower of the file's and the module's start symbol indices */
+             start_sym = CURR_MODULE_ISYM;
+             if (VALID_CURR_FILE && (CURR_FILE_ISYM < CURR_MODULE_ISYM))
+               start_sym = CURR_FILE_ISYM;
+
+             /* For the end address, we scan through the files till we find one
+                that overlaps the current module but ends beyond it; if no such file exists we
+                simply use the module's start address.  
+                (Note, if file entries themselves overlap
+                we take the longest overlapping extension beyond the end of the module...)
+                We assume that modules never overlap. */
+
+             end_adr = CURR_MODULE_END;
+
+             if (VALID_CURR_FILE)
+               {
+                 while (VALID_CURR_FILE && (CURR_FILE_START < end_adr))
+                   {
+
+#ifdef DUMPING
+                     if (dumping)
+                       printf ("Maybe skipping file %s which overlaps with module %s\n",
+                               &vt_bits[(long) qFD[curr_fd].sbFile], mod_name_string);
+#endif
+                     if (CURR_FILE_END > end_adr)
+                       {
+                         TELL_OBJFILE;
+                         warning ("File \"%s\" [0x%x] crosses end of module \"%s\".",
+                                  &vt_bits[(long) qFD[curr_fd].sbFile],
+                                  curr_fd, mod_name_string);
+                         end_adr = CURR_FILE_END;
+                       }
+                     curr_fd++;
+                   }
+                 curr_fd--;    /* back up after going too far */
+               }
+
+             /* Sometimes (compiler bug -- COBOL) the module end address is higher
+                than the start address of the next module, so check for that and
+                adjust accordingly */
+
+             if (VALID_MODULE (curr_md + 1) && (MODULE_START (curr_md + 1) <= end_adr))
+               {
+                 TELL_OBJFILE;
+                 warning ("Module \"%s\" [0x%x] has ending address after starting address of next module; adjusting ending address down.",
+                          mod_name_string, curr_md);
+                 end_adr = MODULE_START (curr_md + 1) - 1;     /* Is -4 (or -8 for 64-bit) better? */
+               }
+             if (VALID_FILE (curr_fd + 1) && (FILE_START (curr_fd + 1) <= end_adr))
+               {
+                 TELL_OBJFILE;
+                 warning ("Module \"%s\" [0x%x] has ending address after starting address of next file; adjusting ending address down.",
+                          mod_name_string, curr_md);
+                 end_adr = FILE_START (curr_fd + 1) - 1;       /* Is -4 (or -8 for 64-bit) better? */
+               }
+
+             /* Use one file to get the full name for the module.  This
+                situation can arise if there is executable code in a #include
+                file.  Each file with code in it gets a qFD.  Files which don't
+                contribute code don't get a qFD, even if they include files
+                which do, e.g.: 
+
+                body.c:                    rtn.h:
+                int x;                     int main() {
+                #include "rtn.h"               return x;
+                }
+
+                There will a qFD for "rtn.h",and a qMD for "body.c",
+                but no qMD for "rtn.h" or qFD for "body.c"!
+
+                We pick the name of the last file to overlap with this
+                module.  C convention is to put include files first.  In a
+                perfect world, we could check names and use the file whose full
+                path name ends with the module name. */
+
+             if (VALID_CURR_FILE)
+               full_name_string = &vt_bits[(long) qFD[curr_fd].sbFile];
+             else
+               full_name_string = mod_name_string;
+
+             /* Check if there are any procedures not handled until now, that
+                begin before the start address we have now, and if so, adjust
+                this psymtab's start address to include them.  This handles routines that
+                are in between file or module ranges for some reason (probably
+                indicates a compiler bug */
+
+             if (CURR_PROC_START < start_adr)
+               {
+                 TELL_OBJFILE;
+                 warning ("Found procedure \"%s\" [0x%x] that is not in any file or module.",
+                          &vt_bits[(long) qPD[curr_pd].sbProc], curr_pd);
+                 start_adr = CURR_PROC_START;
+                 if (CURR_PROC_ISYM < start_sym)
+                   start_sym = CURR_PROC_ISYM;
+               }
+
+#ifdef DUMPING
+             if (dumping)
+               {
+                 printf ("Make new psymtab for module %s (%x to %x), using file %s\n",
+                    mod_name_string, start_adr, end_adr, full_name_string);
+               }
+#endif
+             /* Create the basic psymtab, connecting it in the list
+                for this objfile and pointing its symbol entries
+                to the current end of the symbol areas in the objfile.
+
+                The "ldsymoff" parameter is the byte offset in the LNTT
+                of the first symbol in this file.  Some day we should
+                turn this into an index (fix in hp-symtab-read.c as well).
+                And it's not even the right byte offset, as we're using
+                the size of a union! FIXME!  */
+             pst = hpread_start_psymtab (objfile,
+                                         full_name_string,
+                                         start_adr,    /* Low text address */
+                             (start_sym * sizeof (struct dntt_type_block)),
+             /* ldsymoff */
+                                         global_syms,
+                                         static_syms);
+
+             /* Set up to only enter each class referenced in this module once.  */
+             class_entered = xmalloc (B_BYTES (pxdb_header_p->cd_entries));
+             B_CLRALL (class_entered, pxdb_header_p->cd_entries);
+
+             /* Scan the procedure descriptors for procedures in the current
+                module, based on the starting addresses. */
+
+             syms_in_pst = scan_procs (&curr_pd, qPD, pxdb_header_p->pd_entries,
+                                       start_adr, end_adr, pst, vt_bits, objfile);
+
+             /* Get ending symbol offset */
+
+             end_sym = 0;
+             /* First check for starting index before previous psymtab */
+             if (pst_syms_count && start_sym < pst_syms_array[pst_syms_count - 1].end)
+               {
+                 end_sym = find_next_pst_start (start_sym);
+               }
+             /* Look for next start index of a file or module, or procedure */
+             if (!end_sym)
+               {
+                 int next_file_isym = find_next_file_isym (start_sym, qFD, curr_fd + 1, pxdb_header_p);
+                 int next_module_isym = find_next_module_isym (start_sym, qMD, curr_md + 1, pxdb_header_p);
+                 int next_proc_isym = find_next_proc_isym (start_sym, qPD, curr_pd, pxdb_header_p);
+
+                 if (next_file_isym && next_module_isym)
+                   {
+                     /* pick lower of next file or module start index */
+                     end_sym = min (next_file_isym, next_module_isym);
+                   }
+                 else
+                   {
+                     /* one of them is zero, pick the other */
+                     end_sym = max (next_file_isym, next_module_isym);
+                   }
+
+                 /* As a precaution, check next procedure index too */
+                 if (!end_sym)
+                   end_sym = next_proc_isym;
+                 else
+                   end_sym = min (end_sym, next_proc_isym);
+               }
+
+             /* Couldn't find procedure, file, or module, use globals as default */
+             if (!end_sym)
+               end_sym = pxdb_header_p->globals;
+
+#ifdef DUMPING
+             if (dumping)
+               {
+                 printf ("Module psymtab indices: %x to %x\n", start_sym, end_sym);
+               }
+#endif
+
+             pst = hpread_end_psymtab (pst,
+                                       NULL,   /* psymtab_include_list */
+                                       0,      /* includes_used        */
+                                 end_sym * sizeof (struct dntt_type_block),
+             /* byte index in LNTT of end 
+                = capping symbol offset   
+                = LDSYMOFF of nextfile */
+                                       end_adr,        /* text high */
+                                       NULL,   /* dependency_list      */
+                                       0);     /* dependencies_used    */
+
+             record_pst_syms (start_sym, end_sym);
+
+             if (NULL == pst)
+               warning ("No symbols in psymtab for module \"%s\" [0x%x].", mod_name_string, curr_md);
+
+#ifdef DUMPING
+             if (dumping)
+               {
+                 printf ("Made new psymtab for module %s (%x to %x), sym %x to %x.\n",
+                         mod_name_string, start_adr, end_adr, CURR_MODULE_ISYM, end_sym);
+               }
+#endif
+
+             /* Prepare for the next psymtab. */
+             global_syms = objfile->global_psymbols.next;
+             static_syms = objfile->static_psymbols.next;
+             xfree (class_entered);
+
+             curr_md++;
+             curr_fd++;
+           }                   /* psymtab for module */
+       }                       /* psymtab for non-bogus file or module */
+    }                          /* End of while loop over all files & modules */
+
+  /* There may be some routines after all files and modules -- these will get
+     inserted in a separate new module of their own */
+  if (VALID_CURR_PROC)
+    {
+      start_adr = CURR_PROC_START;
+      end_adr = qPD[pxdb_header_p->pd_entries - 1].adrEnd;
+      TELL_OBJFILE;
+      warning ("Found functions beyond end of all files and modules [0x%x].", curr_pd);
+#ifdef DUMPING
+      if (dumping)
+       {
+         printf ("Orphan functions at end, PD %d and beyond (%x to %x)\n",
+                 curr_pd, start_adr, end_adr);
+       }
+#endif
+      pst = hpread_start_psymtab (objfile,
+                                 "orphans",
+                                 start_adr,    /* Low text address */
+                        (CURR_PROC_ISYM * sizeof (struct dntt_type_block)),
+      /* ldsymoff */
+                                 global_syms,
+                                 static_syms);
+
+      scan_procs (&curr_pd, qPD, pxdb_header_p->pd_entries,
+                 start_adr, end_adr, pst, vt_bits, objfile);
+
+      pst = hpread_end_psymtab (pst,
+                               NULL,   /* psymtab_include_list */
+                               0,      /* includes_used */
+                  pxdb_header_p->globals * sizeof (struct dntt_type_block),
+      /* byte index in LNTT of end 
+         = capping symbol offset   
+         = LDSYMOFF of nextfile */
+                               end_adr,        /* text high  */
+                               NULL,   /* dependency_list */
+                               0);     /* dependencies_used */
+    }
+
+
+#ifdef NEVER_NEVER
+  /* Now build psts for non-module things (in the tail of
+     the LNTT, after the last END MODULE entry).
+
+     If null psts were kept on the chain, this would be
+     a solution.  FIXME */
+  pst = hpread_start_psymtab (objfile,
+                             "globals",
+                             0,
+                             (pxdb_header_p->globals
+                              * sizeof (struct dntt_type_block)),
+                             objfile->global_psymbols.next,
+                             objfile->static_psymbols.next);
+  hpread_end_psymtab (pst,
+                     NULL, 0,
+                     (max_LNTT_sym_index * sizeof (struct dntt_type_block)),
+                     0,
+                     NULL, 0);
+#endif
+
+  clear_pst_syms ();
+
+  return 1;
+
+}                              /* End of hpread_quick_traverse. */
+\f
+
+/* Get appropriate header, based on pxdb type. 
+   Return value: 1 if ok, 0 if not */
+int
+hpread_get_header (struct objfile *objfile, PXDB_header_ptr pxdb_header_p)
+{
+  asection *pinfo_section, *debug_section, *header_section;
+
+#ifdef DUMPING
+  /* Turn on for debugging information */
+  static int dumping = 0;
+#endif
+
+  header_section = bfd_get_section_by_name (objfile->obfd, "$HEADER$");
+  if (!header_section)
+    {
+      /* We don't have either PINFO or DEBUG sections.  But
+         stuff like "libc.sl" has no debug info.  There's no
+         need to warn the user of this, as it may be ok. The
+         caller will figure it out and issue any needed
+         messages. */
+#ifdef DUMPING
+      if (dumping)
+       printf ("==No debug info at all for %s.\n", objfile->name);
+#endif
+
+      return 0;
+    }
+
+  /* We would like either a $DEBUG$ or $PINFO$ section.
+     Once we know which, we can understand the header
+     data (which we have defined to suit the more common
+     $DEBUG$ case). */
+  debug_section = bfd_get_section_by_name (objfile->obfd, "$DEBUG$");
+  pinfo_section = bfd_get_section_by_name (objfile->obfd, "$PINFO$");
+  if (debug_section)
+    {
+      /* The expected case: normal pxdb header. */
+      bfd_get_section_contents (objfile->obfd, header_section,
+                               pxdb_header_p, 0, sizeof (PXDB_header));
+
+      if (!pxdb_header_p->pxdbed)
+       {
+         /* This shouldn't happen if we check in "symfile.c". */
+         return 0;
+       }                       /* DEBUG section */
+    }
+
+  else if (pinfo_section)
+    {
+      /* The DOC case; we need to translate this into a
+         regular header. */
+      DOC_info_PXDB_header doc_header;
+
+#ifdef DUMPING
+      if (dumping)
+       {
+         printf ("==OOps, PINFO, let's try to handle this, %s.\n", objfile->name);
+       }
+#endif
+
+      bfd_get_section_contents (objfile->obfd,
+                               header_section,
+                               &doc_header, 0,
+                               sizeof (DOC_info_PXDB_header));
+
+      if (!doc_header.pxdbed)
+       {
+         /* This shouldn't happen if we check in "symfile.c". */
+         warning ("File \"%s\" not processed by pxdb!", objfile->name);
+         return 0;
+       }
+
+      /* Copy relevent fields to standard header passed in. */
+      pxdb_header_p->pd_entries = doc_header.pd_entries;
+      pxdb_header_p->fd_entries = doc_header.fd_entries;
+      pxdb_header_p->md_entries = doc_header.md_entries;
+      pxdb_header_p->pxdbed = doc_header.pxdbed;
+      pxdb_header_p->bighdr = doc_header.bighdr;
+      pxdb_header_p->sa_header = doc_header.sa_header;
+      pxdb_header_p->inlined = doc_header.inlined;
+      pxdb_header_p->globals = doc_header.globals;
+      pxdb_header_p->time = doc_header.time;
+      pxdb_header_p->pg_entries = doc_header.pg_entries;
+      pxdb_header_p->functions = doc_header.functions;
+      pxdb_header_p->files = doc_header.files;
+      pxdb_header_p->cd_entries = doc_header.cd_entries;
+      pxdb_header_p->aa_entries = doc_header.aa_entries;
+      pxdb_header_p->oi_entries = doc_header.oi_entries;
+      pxdb_header_p->version = doc_header.version;
+    }                          /* PINFO section */
+
+  else
+    {
+#ifdef DUMPING
+      if (dumping)
+       printf ("==No debug info at all for %s.\n", objfile->name);
+#endif
+
+      return 0;
+
+    }
+
+  return 1;
+}                              /* End of hpread_get_header */
+#endif /* QUICK_LOOK_UP */
+\f
+
+/* Initialization for reading native HP C debug symbols from OBJFILE.
+
+   Its only purpose in life is to set up the symbol reader's private
+   per-objfile data structures, and read in the raw contents of the debug
+   sections (attaching pointers to the debug info into the private data
+   structures).
+
+   Since BFD doesn't know how to read debug symbols in a format-independent
+   way (and may never do so...), we have to do it ourselves.  Note we may
+   be called on a file without native HP C debugging symbols.
+
+   FIXME, there should be a cleaner peephole into the BFD environment
+   here. */
+void
+hpread_symfile_init (struct objfile *objfile)
+{
+  asection *vt_section, *slt_section, *lntt_section, *gntt_section;
+
+  /* Allocate struct to keep track of the symfile */
+  objfile->sym_private = (PTR)
+    xmmalloc (objfile->md, sizeof (struct hpread_symfile_info));
+  memset (objfile->sym_private, 0, sizeof (struct hpread_symfile_info));
+
+  /* We haven't read in any types yet.  */
+  DNTT_TYPE_VECTOR (objfile) = 0;
+
+  /* Read in data from the $GNTT$ subspace.  */
+  gntt_section = bfd_get_section_by_name (objfile->obfd, "$GNTT$");
+  if (!gntt_section)
+    return;
+
+  GNTT (objfile)
+    = obstack_alloc (&objfile->symbol_obstack,
+                    bfd_section_size (objfile->obfd, gntt_section));
+
+  bfd_get_section_contents (objfile->obfd, gntt_section, GNTT (objfile),
+                        0, bfd_section_size (objfile->obfd, gntt_section));
+
+  GNTT_SYMCOUNT (objfile)
+    = bfd_section_size (objfile->obfd, gntt_section)
+    / sizeof (struct dntt_type_block);
+
+  /* Read in data from the $LNTT$ subspace.   Also keep track of the number
+     of LNTT symbols.
+
+     FIXME: this could be moved into the psymtab-to-symtab expansion
+     code, and save startup time.  At the moment this data is
+     still used, though.  We'd need a way to tell hp-symtab-read.c
+     whether or not to load the LNTT. */
+  lntt_section = bfd_get_section_by_name (objfile->obfd, "$LNTT$");
+  if (!lntt_section)
+    return;
+
+  LNTT (objfile)
+    = obstack_alloc (&objfile->symbol_obstack,
+                    bfd_section_size (objfile->obfd, lntt_section));
+
+  bfd_get_section_contents (objfile->obfd, lntt_section, LNTT (objfile),
+                        0, bfd_section_size (objfile->obfd, lntt_section));
+
+  LNTT_SYMCOUNT (objfile)
+    = bfd_section_size (objfile->obfd, lntt_section)
+    / sizeof (struct dntt_type_block);
+
+  /* Read in data from the $SLT$ subspace.  $SLT$ contains information
+     on source line numbers.  */
+  slt_section = bfd_get_section_by_name (objfile->obfd, "$SLT$");
+  if (!slt_section)
+    return;
+
+  SLT (objfile) =
+    obstack_alloc (&objfile->symbol_obstack,
+                  bfd_section_size (objfile->obfd, slt_section));
+
+  bfd_get_section_contents (objfile->obfd, slt_section, SLT (objfile),
+                         0, bfd_section_size (objfile->obfd, slt_section));
+
+  /* Read in data from the $VT$ subspace.  $VT$ contains things like
+     names and constants.  Keep track of the number of symbols in the VT.  */
+  vt_section = bfd_get_section_by_name (objfile->obfd, "$VT$");
+  if (!vt_section)
+    return;
+
+  VT_SIZE (objfile) = bfd_section_size (objfile->obfd, vt_section);
+
+  VT (objfile) =
+    (char *) obstack_alloc (&objfile->symbol_obstack,
+                           VT_SIZE (objfile));
+
+  bfd_get_section_contents (objfile->obfd, vt_section, VT (objfile),
+                           0, VT_SIZE (objfile));
+}
+
+/* Scan and build partial symbols for a symbol file.
+
+   The minimal symbol table (either SOM or HP a.out) has already been
+   read in; all we need to do is setup partial symbols based on the
+   native debugging information.
+
+   Note that the minimal table is produced by the linker, and has
+   only global routines in it; the psymtab is based on compiler-
+   generated debug information and has non-global
+   routines in it as well as files and class information.
+
+   We assume hpread_symfile_init has been called to initialize the
+   symbol reader's private data structures.
+
+   MAINLINE is true if we are reading the main symbol table (as
+   opposed to a shared lib or dynamically loaded file). */
+
+void
+hpread_build_psymtabs (struct objfile *objfile, int mainline)
+{
+
+#ifdef DUMPING
+  /* Turn this on to get debugging output. */
+  static int dumping = 0;
+#endif
+
+  char *namestring;
+  int past_first_source_file = 0;
+  struct cleanup *old_chain;
+
+  int hp_symnum, symcount, i;
+  int scan_start = 0;
+
+  union dnttentry *dn_bufp;
+  unsigned long valu;
+  char *p;
+  int texthigh = 0;
+  int have_name = 0;
+
+  /* Current partial symtab */
+  struct partial_symtab *pst;
+
+  /* List of current psymtab's include files */
+  char **psymtab_include_list;
+  int includes_allocated;
+  int includes_used;
+
+  /* Index within current psymtab dependency list */
+  struct partial_symtab **dependency_list;
+  int dependencies_used, dependencies_allocated;
+
+  /* Just in case the stabs reader left turds lying around.  */
+  free_pending_blocks ();
+  make_cleanup (really_free_pendings, 0);
+
+  pst = (struct partial_symtab *) 0;
+
+  /* We shouldn't use alloca, instead use malloc/free.  Doing so avoids
+     a number of problems with cross compilation and creating useless holes
+     in the stack when we have to allocate new entries.  FIXME.  */
+
+  includes_allocated = 30;
+  includes_used = 0;
+  psymtab_include_list = (char **) alloca (includes_allocated *
+                                          sizeof (char *));
+
+  dependencies_allocated = 30;
+  dependencies_used = 0;
+  dependency_list =
+    (struct partial_symtab **) alloca (dependencies_allocated *
+                                      sizeof (struct partial_symtab *));
+
+  old_chain = make_cleanup_free_objfile (objfile);
+
+  last_source_file = 0;
+
+#ifdef QUICK_LOOK_UP
+  {
+    /* Begin code for new-style loading of quick look-up tables. */
+
+    /* elz: this checks whether the file has beeen processed by pxdb.
+       If not we would like to try to read the psymbols in
+       anyway, but it turns out to be not so easy. So this could 
+       actually be commented out, but I leave it in, just in case
+       we decide to add support for non-pxdb-ed stuff in the future. */
+    PXDB_header pxdb_header;
+    int found_modules_in_program;
+
+    if (hpread_get_header (objfile, &pxdb_header))
+      {
+       /* Build a minimal table.  No types, no global variables,
+          no include files.... */
+#ifdef DUMPING
+       if (dumping)
+         printf ("\nNew method for %s\n", objfile->name);
+#endif
+
+       /* elz: quick_traverse returns true if it found
+          some modules in the main source file, other
+          than those in end.c
+          In C and C++, all the files have MODULES entries
+          in the LNTT, and the quick table traverse is all 
+          based on finding these MODULES entries. Without 
+          those it cannot work. 
+          It happens that F77 programs don't have MODULES
+          so the quick traverse gets confused. F90 programs
+          have modules, and the quick method still works.
+          So, if modules (other than those in end.c) are
+          not found we give up on the quick table stuff, 
+          and fall back on the slower method  */
+       found_modules_in_program = hpread_quick_traverse (objfile,
+                                                         GNTT (objfile),
+                                                         VT (objfile),
+                                                         &pxdb_header);
+
+       discard_cleanups (old_chain);
+
+       /* Set up to scan the global section of the LNTT.
+
+          This field is not always correct: if there are
+          no globals, it will point to the last record in
+          the regular LNTT, which is usually an END MODULE.
+
+          Since it might happen that there could be a file
+          with just one global record, there's no way to
+          tell other than by looking at the record, so that's
+          done below. */
+       if (found_modules_in_program)
+         scan_start = pxdb_header.globals;
+      }
+#ifdef DUMPING
+    else
+      {
+       if (dumping)
+         printf ("\nGoing on to old method for %s\n", objfile->name);
+      }
+#endif
+  }
+#endif /* QUICK_LOOK_UP */
+
+  /* Make two passes, one over the GNTT symbols, the other for the
+     LNTT symbols.
+
+     JB comment: above isn't true--they only make one pass, over
+     the LNTT.  */
+  for (i = 0; i < 1; i++)
+    {
+      int within_function = 0;
+
+      if (i)
+       symcount = GNTT_SYMCOUNT (objfile);
+      else
+       symcount = LNTT_SYMCOUNT (objfile);
+
+
+      for (hp_symnum = scan_start; hp_symnum < symcount; hp_symnum++)
+       {
+         QUIT;
+         if (i)
+           dn_bufp = hpread_get_gntt (hp_symnum, objfile);
+         else
+           dn_bufp = hpread_get_lntt (hp_symnum, objfile);
+
+         if (dn_bufp->dblock.extension)
+           continue;
+
+         /* Only handle things which are necessary for minimal symbols.
+            everything else is ignored.  */
+         switch (dn_bufp->dblock.kind)
+           {
+           case DNTT_TYPE_SRCFILE:
+             {
+#ifdef QUICK_LOOK_UP
+               if (scan_start == hp_symnum
+                   && symcount == hp_symnum + 1)
+                 {
+                   /* If there are NO globals in an executable,
+                      PXDB's index to the globals will point to
+                      the last record in the file, which 
+                      could be this record. (this happened for F77 libraries)
+                      ignore it and be done! */
+                   continue;
+                 }
+#endif /* QUICK_LOOK_UP */
+
+               /* A source file of some kind.  Note this may simply
+                  be an included file.  */
+               SET_NAMESTRING (dn_bufp, &namestring, objfile);
+
+               /* Check if this is the source file we are already working
+                  with.  */
+               if (pst && !strcmp (namestring, pst->filename))
+                 continue;
+
+               /* Check if this is an include file, if so check if we have
+                  already seen it.  Add it to the include list */
+               p = strrchr (namestring, '.');
+               if (!strcmp (p, ".h"))
+                 {
+                   int j, found;
+
+                   found = 0;
+                   for (j = 0; j < includes_used; j++)
+                     if (!strcmp (namestring, psymtab_include_list[j]))
+                       {
+                         found = 1;
+                         break;
+                       }
+                   if (found)
+                     continue;
+
+                   /* Add it to the list of includes seen so far and
+                      allocate more include space if necessary.  */
+                   psymtab_include_list[includes_used++] = namestring;
+                   if (includes_used >= includes_allocated)
+                     {
+                       char **orig = psymtab_include_list;
+
+                       psymtab_include_list = (char **)
+                         alloca ((includes_allocated *= 2) *
+                                 sizeof (char *));
+                       memcpy ((PTR) psymtab_include_list, (PTR) orig,
+                               includes_used * sizeof (char *));
+                     }
+                   continue;
+                 }
+
+               if (pst)
+                 {
+                   if (!have_name)
+                     {
+                       pst->filename = (char *)
+                         obstack_alloc (&pst->objfile->psymbol_obstack,
+                                        strlen (namestring) + 1);
+                       strcpy (pst->filename, namestring);
+                       have_name = 1;
+                       continue;
+                     }
+                   continue;
+                 }
+
+               /* This is a bonafide new source file.
+                  End the current partial symtab and start a new one.  */
+
+               if (pst && past_first_source_file)
+                 {
+                   hpread_end_psymtab (pst, psymtab_include_list,
+                                       includes_used,
+                                       (hp_symnum
+                                        * sizeof (struct dntt_type_block)),
+                                       texthigh,
+                                       dependency_list, dependencies_used);
+                   pst = (struct partial_symtab *) 0;
+                   includes_used = 0;
+                   dependencies_used = 0;
+                 }
+               else
+                 past_first_source_file = 1;
+
+               valu = hpread_get_textlow (i, hp_symnum, objfile, symcount);
+               valu += ANOFFSET (objfile->section_offsets, SECT_OFF_TEXT (objfile));
+               pst = hpread_start_psymtab (objfile,
+                                           namestring, valu,
+                                           (hp_symnum
+                                        * sizeof (struct dntt_type_block)),
+                                           objfile->global_psymbols.next,
+                                           objfile->static_psymbols.next);
+               texthigh = valu;
+               have_name = 1;
+               continue;
+             }
+
+           case DNTT_TYPE_MODULE:
+             /* A source file.  It's still unclear to me what the
+                real difference between a DNTT_TYPE_SRCFILE and DNTT_TYPE_MODULE
+                is supposed to be.  */
+
+             /* First end the previous psymtab */
+             if (pst)
+               {
+                 hpread_end_psymtab (pst, psymtab_include_list, includes_used,
+                                     ((hp_symnum - 1)
+                                      * sizeof (struct dntt_type_block)),
+                                     texthigh,
+                                     dependency_list, dependencies_used);
+                 pst = (struct partial_symtab *) 0;
+                 includes_used = 0;
+                 dependencies_used = 0;
+                 have_name = 0;
+               }
+
+             /* Now begin a new module and a new psymtab for it */
+             SET_NAMESTRING (dn_bufp, &namestring, objfile);
+             valu = hpread_get_textlow (i, hp_symnum, objfile, symcount);
+             valu += ANOFFSET (objfile->section_offsets, SECT_OFF_TEXT (objfile));
+             if (!pst)
+               {
+                 pst = hpread_start_psymtab (objfile,
+                                             namestring, valu,
+                                             (hp_symnum
+                                        * sizeof (struct dntt_type_block)),
+                                             objfile->global_psymbols.next,
+                                             objfile->static_psymbols.next);
+                 texthigh = valu;
+                 have_name = 0;
+               }
+             continue;
+
+           case DNTT_TYPE_FUNCTION:
+           case DNTT_TYPE_ENTRY:
+             /* The beginning of a function.  DNTT_TYPE_ENTRY may also denote
+                a secondary entry point.  */
+             valu = dn_bufp->dfunc.hiaddr + ANOFFSET (objfile->section_offsets,
+                                                      SECT_OFF_TEXT (objfile));
+             if (valu > texthigh)
+               texthigh = valu;
+             valu = dn_bufp->dfunc.lowaddr +
+               ANOFFSET (objfile->section_offsets, SECT_OFF_TEXT (objfile));
+             SET_NAMESTRING (dn_bufp, &namestring, objfile);
+             if (dn_bufp->dfunc.global)
+               add_psymbol_to_list (namestring, strlen (namestring),
+                                    VAR_NAMESPACE, LOC_BLOCK,
+                                    &objfile->global_psymbols, valu,
+                                    0, language_unknown, objfile);
+             else
+               add_psymbol_to_list (namestring, strlen (namestring),
+                                    VAR_NAMESPACE, LOC_BLOCK,
+                                    &objfile->static_psymbols, valu,
+                                    0, language_unknown, objfile);
+             within_function = 1;
+             continue;
+
+           case DNTT_TYPE_DOC_FUNCTION:
+             valu = dn_bufp->ddocfunc.hiaddr + ANOFFSET (objfile->section_offsets,
+                                                         SECT_OFF_TEXT (objfile));
+             if (valu > texthigh)
+               texthigh = valu;
+             valu = dn_bufp->ddocfunc.lowaddr +
+               ANOFFSET (objfile->section_offsets, SECT_OFF_TEXT (objfile));
+             SET_NAMESTRING (dn_bufp, &namestring, objfile);
+             if (dn_bufp->ddocfunc.global)
+               add_psymbol_to_list (namestring, strlen (namestring),
+                                    VAR_NAMESPACE, LOC_BLOCK,
+                                    &objfile->global_psymbols, valu,
+                                    0, language_unknown, objfile);
+             else
+               add_psymbol_to_list (namestring, strlen (namestring),
+                                    VAR_NAMESPACE, LOC_BLOCK,
+                                    &objfile->static_psymbols, valu,
+                                    0, language_unknown, objfile);
+             within_function = 1;
+             continue;
+
+           case DNTT_TYPE_BEGIN:
+           case DNTT_TYPE_END:
+             /* We don't check MODULE end here, because there can be
+                symbols beyond the module end which properly belong to the
+                current psymtab -- so we wait till the next MODULE start */
+
+
+#ifdef QUICK_LOOK_UP
+             if (scan_start == hp_symnum
+                 && symcount == hp_symnum + 1)
+               {
+                 /* If there are NO globals in an executable,
+                    PXDB's index to the globals will point to
+                    the last record in the file, which is
+                    probably an END MODULE, i.e. this record.
+                    ignore it and be done! */
+                 continue;
+               }
+#endif /* QUICK_LOOK_UP */
+
+             /* Scope block begin/end.  We only care about function
+                and file blocks right now.  */
+
+             if ((dn_bufp->dend.endkind == DNTT_TYPE_FUNCTION) ||
+                 (dn_bufp->dend.endkind == DNTT_TYPE_DOC_FUNCTION))
+               within_function = 0;
+             continue;
+
+           case DNTT_TYPE_SVAR:
+           case DNTT_TYPE_DVAR:
+           case DNTT_TYPE_TYPEDEF:
+           case DNTT_TYPE_TAGDEF:
+             {
+               /* Variables, typedefs an the like.  */
+               enum address_class storage;
+               namespace_enum namespace;
+
+               /* Don't add locals to the partial symbol table.  */
+               if (within_function
+                   && (dn_bufp->dblock.kind == DNTT_TYPE_SVAR
+                       || dn_bufp->dblock.kind == DNTT_TYPE_DVAR))
+                 continue;
+
+               /* TAGDEFs go into the structure namespace.  */
+               if (dn_bufp->dblock.kind == DNTT_TYPE_TAGDEF)
+                 namespace = STRUCT_NAMESPACE;
+               else
+                 namespace = VAR_NAMESPACE;
+
+               /* What kind of "storage" does this use?  */
+               if (dn_bufp->dblock.kind == DNTT_TYPE_SVAR)
+                 storage = LOC_STATIC;
+               else if (dn_bufp->dblock.kind == DNTT_TYPE_DVAR
+                        && dn_bufp->ddvar.regvar)
+                 storage = LOC_REGISTER;
+               else if (dn_bufp->dblock.kind == DNTT_TYPE_DVAR)
+                 storage = LOC_LOCAL;
+               else
+                 storage = LOC_UNDEF;
+
+               SET_NAMESTRING (dn_bufp, &namestring, objfile);
+               if (!pst)
+                 {
+                   pst = hpread_start_psymtab (objfile,
+                                               "globals", 0,
+                                               (hp_symnum
+                                        * sizeof (struct dntt_type_block)),
+                                             objfile->global_psymbols.next,
+                                            objfile->static_psymbols.next);
+                 }
+
+               /* Compute address of the data symbol */
+               valu = dn_bufp->dsvar.location;
+               /* Relocate in case it's in a shared library */
+               if (storage == LOC_STATIC)
+                 valu += ANOFFSET (objfile->section_offsets, SECT_OFF_DATA (objfile));
+
+               /* Luckily, dvar, svar, typedef, and tagdef all
+                  have their "global" bit in the same place, so it works
+                  (though it's bad programming practice) to reference
+                  "dsvar.global" even though we may be looking at
+                  any of the above four types. */
+               if (dn_bufp->dsvar.global)
+                 {
+                   add_psymbol_to_list (namestring, strlen (namestring),
+                                        namespace, storage,
+                                        &objfile->global_psymbols,
+                                        valu,
+                                        0, language_unknown, objfile);
+                 }
+               else
+                 {
+                   add_psymbol_to_list (namestring, strlen (namestring),
+                                        namespace, storage,
+                                        &objfile->static_psymbols,
+                                        valu,
+                                        0, language_unknown, objfile);
+                 }
+
+               /* For TAGDEF's, the above code added the tagname to the
+                  struct namespace. This will cause tag "t" to be found
+                  on a reference of the form "(struct t) x". But for
+                  C++ classes, "t" will also be a typename, which we
+                  want to find on a reference of the form "ptype t".
+                  Therefore, we also add "t" to the var namespace.
+                  Do the same for enum's due to the way aCC generates
+                  debug info for these (see more extended comment
+                  in hp-symtab-read.c).
+                  We do the same for templates, so that "ptype t"
+                  where "t" is a template also works. */
+               if (dn_bufp->dblock.kind == DNTT_TYPE_TAGDEF &&
+                 dn_bufp->dtype.type.dnttp.index < LNTT_SYMCOUNT (objfile))
+                 {
+                   int global = dn_bufp->dtag.global;
+                   /* Look ahead to see if it's a C++ class */
+                   dn_bufp = hpread_get_lntt (dn_bufp->dtype.type.dnttp.index, objfile);
+                   if (dn_bufp->dblock.kind == DNTT_TYPE_CLASS ||
+                       dn_bufp->dblock.kind == DNTT_TYPE_ENUM ||
+                       dn_bufp->dblock.kind == DNTT_TYPE_TEMPLATE)
+                     {
+                       if (global)
+                         {
+                           add_psymbol_to_list (namestring, strlen (namestring),
+                                                VAR_NAMESPACE, storage,
+                                                &objfile->global_psymbols,
+                                                dn_bufp->dsvar.location,
+                                             0, language_unknown, objfile);
+                         }
+                       else
+                         {
+                           add_psymbol_to_list (namestring, strlen (namestring),
+                                                VAR_NAMESPACE, storage,
+                                                &objfile->static_psymbols,
+                                                dn_bufp->dsvar.location,
+                                             0, language_unknown, objfile);
+                         }
+                     }
+                 }
+             }
+             continue;
+
+           case DNTT_TYPE_MEMENUM:
+           case DNTT_TYPE_CONST:
+             /* Constants and members of enumerated types.  */
+             SET_NAMESTRING (dn_bufp, &namestring, objfile);
+             if (!pst)
+               {
+                 pst = hpread_start_psymtab (objfile,
+                                             "globals", 0,
+                                             (hp_symnum
+                                        * sizeof (struct dntt_type_block)),
+                                             objfile->global_psymbols.next,
+                                             objfile->static_psymbols.next);
+               }
+             if (dn_bufp->dconst.global)
+               add_psymbol_to_list (namestring, strlen (namestring),
+                                    VAR_NAMESPACE, LOC_CONST,
+                                    &objfile->global_psymbols, 0,
+                                    0, language_unknown, objfile);
+             else
+               add_psymbol_to_list (namestring, strlen (namestring),
+                                    VAR_NAMESPACE, LOC_CONST,
+                                    &objfile->static_psymbols, 0,
+                                    0, language_unknown, objfile);
+             continue;
+           default:
+             continue;
+           }
+       }
+    }
+
+  /* End any pending partial symbol table. */
+  if (pst)
+    {
+      hpread_end_psymtab (pst, psymtab_include_list, includes_used,
+                         hp_symnum * sizeof (struct dntt_type_block),
+                         0, dependency_list, dependencies_used);
+    }
+
+  discard_cleanups (old_chain);
+}
+
+/* Perform any local cleanups required when we are done with a particular
+   objfile.  I.E, we are in the process of discarding all symbol information
+   for an objfile, freeing up all memory held for it, and unlinking the
+   objfile struct from the global list of known objfiles. */
+
+void
+hpread_symfile_finish (struct objfile *objfile)
+{
+  if (objfile->sym_private != NULL)
+    {
+      xmfree (objfile->md, objfile->sym_private);
+    }
+}
+\f
+
+/* The remaining functions are all for internal use only.  */
+
+/* Various small functions to get entries in the debug symbol sections.  */
+
+union dnttentry *
+hpread_get_lntt (int index, struct objfile *objfile)
+{
+  return (union dnttentry *)
+    &(LNTT (objfile)[(index * sizeof (struct dntt_type_block))]);
+}
+
+static union dnttentry *
+hpread_get_gntt (int index, struct objfile *objfile)
+{
+  return (union dnttentry *)
+    &(GNTT (objfile)[(index * sizeof (struct dntt_type_block))]);
+}
+
+union sltentry *
+hpread_get_slt (int index, struct objfile *objfile)
+{
+  return (union sltentry *) &(SLT (objfile)[index * sizeof (union sltentry)]);
+}
+
+/* Get the low address associated with some symbol (typically the start
+   of a particular source file or module).  Since that information is not
+   stored as part of the DNTT_TYPE_MODULE or DNTT_TYPE_SRCFILE symbol we
+   must infer it from the existence of DNTT_TYPE_FUNCTION symbols.  */
+
+static unsigned long
+hpread_get_textlow (int global, int index, struct objfile *objfile,
+                   int symcount)
+{
+  union dnttentry *dn_bufp;
+  struct minimal_symbol *msymbol;
+
+  /* Look for a DNTT_TYPE_FUNCTION symbol.  */
+  if (index < symcount)                /* symcount is the number of symbols in */
+    {                          /*   the dbinfo, LNTT table */
+      do
+       {
+         if (global)
+           dn_bufp = hpread_get_gntt (index++, objfile);
+         else
+           dn_bufp = hpread_get_lntt (index++, objfile);
+       }
+      while (dn_bufp->dblock.kind != DNTT_TYPE_FUNCTION
+            && dn_bufp->dblock.kind != DNTT_TYPE_DOC_FUNCTION
+            && dn_bufp->dblock.kind != DNTT_TYPE_END
+            && index < symcount);
+    }
+
+  /* Avoid going past a DNTT_TYPE_END when looking for a DNTT_TYPE_FUNCTION.  This
+     might happen when a sourcefile has no functions.  */
+  if (dn_bufp->dblock.kind == DNTT_TYPE_END)
+    return 0;
+
+  /* Avoid going past the end of the LNTT file */
+  if (index == symcount)
+    return 0;
+
+  /* The minimal symbols are typically more accurate for some reason.  */
+  if (dn_bufp->dblock.kind == DNTT_TYPE_FUNCTION)
+    msymbol = lookup_minimal_symbol (dn_bufp->dfunc.name + VT (objfile), NULL,
+                                    objfile);
+  else                         /* must be a DNTT_TYPE_DOC_FUNCTION */
+    msymbol = lookup_minimal_symbol (dn_bufp->ddocfunc.name + VT (objfile), NULL,
+                                    objfile);
+
+  if (msymbol)
+    return SYMBOL_VALUE_ADDRESS (msymbol);
+  else
+    return dn_bufp->dfunc.lowaddr;
+}
+
+/* Allocate and partially fill a partial symtab.  It will be
+   completely filled at the end of the symbol list.
+
+   SYMFILE_NAME is the name of the symbol-file we are reading from, and ADDR
+   is the address relative to which its symbols are (incremental) or 0
+   (normal). */
+
+static struct partial_symtab *
+hpread_start_psymtab (struct objfile *objfile, char *filename,
+                     CORE_ADDR textlow, int ldsymoff,
+                     struct partial_symbol **global_syms,
+                     struct partial_symbol **static_syms)
+{
+  int offset = ANOFFSET (objfile->section_offsets, SECT_OFF_TEXT (objfile));
+  extern void hpread_psymtab_to_symtab ();
+  struct partial_symtab *result =
+  start_psymtab_common (objfile, objfile->section_offsets,
+                       filename, textlow, global_syms, static_syms);
+
+  result->textlow += offset;
+  result->read_symtab_private = (char *)
+    obstack_alloc (&objfile->psymbol_obstack, sizeof (struct symloc));
+  LDSYMOFF (result) = ldsymoff;
+  result->read_symtab = hpread_psymtab_to_symtab;
+
+  return result;
+}
+\f
+
+/* Close off the current usage of PST.  
+   Returns PST or NULL if the partial symtab was empty and thrown away.
+
+   capping_symbol_offset  --Byte index in LNTT or GNTT of the
+   last symbol processed during the build
+   of the previous pst.
+
+   FIXME:  List variables and peculiarities of same.  */
+
+static struct partial_symtab *
+hpread_end_psymtab (struct partial_symtab *pst, char **include_list,
+                   int num_includes, int capping_symbol_offset,
+                   CORE_ADDR capping_text,
+                   struct partial_symtab **dependency_list,
+                   int number_dependencies)
+{
+  int i;
+  struct objfile *objfile = pst->objfile;
+  int offset = ANOFFSET (pst->section_offsets, SECT_OFF_TEXT (objfile));
+
+#ifdef DUMPING
+  /* Turn on to see what kind of a psymtab we've built. */
+  static int dumping = 0;
+#endif
+
+  if (capping_symbol_offset != -1)
+    LDSYMLEN (pst) = capping_symbol_offset - LDSYMOFF (pst);
+  else
+    LDSYMLEN (pst) = 0;
+  pst->texthigh = capping_text + offset;
+
+  pst->n_global_syms =
+    objfile->global_psymbols.next - (objfile->global_psymbols.list + pst->globals_offset);
+  pst->n_static_syms =
+    objfile->static_psymbols.next - (objfile->static_psymbols.list + pst->statics_offset);
+
+#ifdef DUMPING
+  if (dumping)
+    {
+      printf ("\nPst %s, LDSYMOFF %x (%x), LDSYMLEN %x (%x), globals %d, statics %d\n",
+             pst->filename,
+             LDSYMOFF (pst),
+             LDSYMOFF (pst) / sizeof (struct dntt_type_block),
+             LDSYMLEN (pst),
+             LDSYMLEN (pst) / sizeof (struct dntt_type_block),
+             pst->n_global_syms, pst->n_static_syms);
+    }
+#endif
+
+  pst->number_of_dependencies = number_dependencies;
+  if (number_dependencies)
+    {
+      pst->dependencies = (struct partial_symtab **)
+       obstack_alloc (&objfile->psymbol_obstack,
+                   number_dependencies * sizeof (struct partial_symtab *));
+      memcpy (pst->dependencies, dependency_list,
+             number_dependencies * sizeof (struct partial_symtab *));
+    }
+  else
+    pst->dependencies = 0;
+
+  for (i = 0; i < num_includes; i++)
+    {
+      struct partial_symtab *subpst =
+      allocate_psymtab (include_list[i], objfile);
+
+      subpst->section_offsets = pst->section_offsets;
+      subpst->read_symtab_private =
+       (char *) obstack_alloc (&objfile->psymbol_obstack,
+                               sizeof (struct symloc));
+      LDSYMOFF (subpst) =
+       LDSYMLEN (subpst) =
+       subpst->textlow =
+       subpst->texthigh = 0;
+
+      /* We could save slight bits of space by only making one of these,
+         shared by the entire set of include files.  FIXME-someday.  */
+      subpst->dependencies = (struct partial_symtab **)
+       obstack_alloc (&objfile->psymbol_obstack,
+                      sizeof (struct partial_symtab *));
+      subpst->dependencies[0] = pst;
+      subpst->number_of_dependencies = 1;
+
+      subpst->globals_offset =
+       subpst->n_global_syms =
+       subpst->statics_offset =
+       subpst->n_static_syms = 0;
+
+      subpst->readin = 0;
+      subpst->symtab = 0;
+      subpst->read_symtab = pst->read_symtab;
+    }
+
+  sort_pst_symbols (pst);
+
+  /* If there is already a psymtab or symtab for a file of this name, remove it.
+     (If there is a symtab, more drastic things also happen.)
+     This happens in VxWorks.  */
+  free_named_symtabs (pst->filename);
+
+  if (num_includes == 0
+      && number_dependencies == 0
+      && pst->n_global_syms == 0
+      && pst->n_static_syms == 0)
+    {
+      /* Throw away this psymtab, it's empty.  We can't deallocate it, since
+         it is on the obstack, but we can forget to chain it on the list. 
+         Empty psymtabs happen as a result of header files which don't have
+         any symbols in them.  There can be a lot of them.  But this check
+         is wrong, in that a psymtab with N_SLINE entries but nothing else
+         is not empty, but we don't realize that.  Fixing that without slowing
+         things down might be tricky.
+         It's also wrong if we're using the quick look-up tables, as
+         we can get empty psymtabs from modules with no routines in
+         them. */
+
+      discard_psymtab (pst);
+
+      /* Indicate that psymtab was thrown away.  */
+      pst = (struct partial_symtab *) NULL;
+
+    }
+  return pst;
+}
+
+\f
+/* Get the nesting depth for the source line identified by INDEX.  */
+
+static unsigned long
+hpread_get_scope_start (sltpointer index, struct objfile *objfile)
+{
+  union sltentry *sl_bufp;
+
+  sl_bufp = hpread_get_slt (index, objfile);
+  return sl_bufp->sspec.backptr.dnttp.index;
+}
+
+/* Get the source line number the the line identified by INDEX.  */
+
+static unsigned long
+hpread_get_line (sltpointer index, struct objfile *objfile)
+{
+  union sltentry *sl_bufp;
+
+  sl_bufp = hpread_get_slt (index, objfile);
+  return sl_bufp->snorm.line;
+}
+
+/* Find the code address associated with a given sltpointer */
+
+static CORE_ADDR
+hpread_get_location (sltpointer index, struct objfile *objfile)
+{
+  union sltentry *sl_bufp;
+  int i;
+
+  /* code location of special sltentrys is determined from context */
+  sl_bufp = hpread_get_slt (index, objfile);
+
+  if (sl_bufp->snorm.sltdesc == SLT_END)
+    {
+      /* find previous normal sltentry and get address */
+      for (i = 0; ((sl_bufp->snorm.sltdesc != SLT_NORMAL) &&
+                  (sl_bufp->snorm.sltdesc != SLT_NORMAL_OFFSET) &&
+                  (sl_bufp->snorm.sltdesc != SLT_EXIT)); i++)
+       sl_bufp = hpread_get_slt (index - i, objfile);
+      if (sl_bufp->snorm.sltdesc == SLT_NORMAL_OFFSET)
+       return sl_bufp->snormoff.address;
+      else
+       return sl_bufp->snorm.address;
+    }
+
+  /* find next normal sltentry and get address */
+  for (i = 0; ((sl_bufp->snorm.sltdesc != SLT_NORMAL) &&
+              (sl_bufp->snorm.sltdesc != SLT_NORMAL_OFFSET) &&
+              (sl_bufp->snorm.sltdesc != SLT_EXIT)); i++)
+    sl_bufp = hpread_get_slt (index + i, objfile);
+  if (sl_bufp->snorm.sltdesc == SLT_NORMAL_OFFSET)
+    return sl_bufp->snormoff.address;
+  else
+    return sl_bufp->snorm.address;
+}
+\f
+
+/* Return 1 if an HP debug symbol of type KIND has a name associated with
+ * it, else return 0. (This function is not currently used, but I'll
+ * leave it here in case it proves useful later on. - RT).
+ */
+
+int
+hpread_has_name (enum dntt_entry_type kind)
+{
+  switch (kind)
+    {
+    case DNTT_TYPE_SRCFILE:
+    case DNTT_TYPE_MODULE:
+    case DNTT_TYPE_FUNCTION:
+    case DNTT_TYPE_DOC_FUNCTION:
+    case DNTT_TYPE_ENTRY:
+    case DNTT_TYPE_IMPORT:
+    case DNTT_TYPE_LABEL:
+    case DNTT_TYPE_FPARAM:
+    case DNTT_TYPE_SVAR:
+    case DNTT_TYPE_DVAR:
+    case DNTT_TYPE_CONST:
+    case DNTT_TYPE_TYPEDEF:
+    case DNTT_TYPE_TAGDEF:
+    case DNTT_TYPE_MEMENUM:
+    case DNTT_TYPE_FIELD:
+    case DNTT_TYPE_SA:
+    case DNTT_TYPE_BLOCKDATA:
+    case DNTT_TYPE_MEMFUNC:
+    case DNTT_TYPE_DOC_MEMFUNC:
+      return 1;
+
+    case DNTT_TYPE_BEGIN:
+    case DNTT_TYPE_END:
+    case DNTT_TYPE_POINTER:
+    case DNTT_TYPE_ENUM:
+    case DNTT_TYPE_SET:
+    case DNTT_TYPE_ARRAY:
+    case DNTT_TYPE_STRUCT:
+    case DNTT_TYPE_UNION:
+    case DNTT_TYPE_VARIANT:
+    case DNTT_TYPE_FILE:
+    case DNTT_TYPE_FUNCTYPE:
+    case DNTT_TYPE_SUBRANGE:
+    case DNTT_TYPE_WITH:
+    case DNTT_TYPE_COMMON:
+    case DNTT_TYPE_COBSTRUCT:
+    case DNTT_TYPE_XREF:
+    case DNTT_TYPE_MACRO:
+    case DNTT_TYPE_CLASS_SCOPE:
+    case DNTT_TYPE_REFERENCE:
+    case DNTT_TYPE_PTRMEM:
+    case DNTT_TYPE_PTRMEMFUNC:
+    case DNTT_TYPE_CLASS:
+    case DNTT_TYPE_GENFIELD:
+    case DNTT_TYPE_VFUNC:
+    case DNTT_TYPE_MEMACCESS:
+    case DNTT_TYPE_INHERITANCE:
+    case DNTT_TYPE_FRIEND_CLASS:
+    case DNTT_TYPE_FRIEND_FUNC:
+    case DNTT_TYPE_MODIFIER:
+    case DNTT_TYPE_OBJECT_ID:
+    case DNTT_TYPE_TEMPLATE:
+    case DNTT_TYPE_TEMPLATE_ARG:
+    case DNTT_TYPE_FUNC_TEMPLATE:
+    case DNTT_TYPE_LINK:
+      /* DNTT_TYPE_DYN_ARRAY_DESC ? */
+      /* DNTT_TYPE_DESC_SUBRANGE ? */
+      /* DNTT_TYPE_BEGIN_EXT ? */
+      /* DNTT_TYPE_INLN ? */
+      /* DNTT_TYPE_INLN_LIST ? */
+      /* DNTT_TYPE_ALIAS ? */
+    default:
+      return 0;
+    }
+}
+
+/* Do the dirty work of reading in the full symbol from a partial symbol
+   table.  */
+
+static void
+hpread_psymtab_to_symtab_1 (struct partial_symtab *pst)
+{
+  struct cleanup *old_chain;
+  int i;
+
+  /* Get out quick if passed junk.  */
+  if (!pst)
+    return;
+
+  /* Complain if we've already read in this symbol table.  */
+  if (pst->readin)
+    {
+      fprintf_unfiltered (gdb_stderr, "Psymtab for %s already read in."
+                         "  Shouldn't happen.\n",
+                         pst->filename);
+      return;
+    }
+
+  /* Read in all partial symtabs on which this one is dependent */
+  for (i = 0; i < pst->number_of_dependencies; i++)
+    if (!pst->dependencies[i]->readin)
+      {
+       /* Inform about additional files that need to be read in.  */
+       if (info_verbose)
+         {
+           fputs_filtered (" ", gdb_stdout);
+           wrap_here ("");
+           fputs_filtered ("and ", gdb_stdout);
+           wrap_here ("");
+           printf_filtered ("%s...", pst->dependencies[i]->filename);
+           wrap_here ("");     /* Flush output */
+           gdb_flush (gdb_stdout);
+         }
+       hpread_psymtab_to_symtab_1 (pst->dependencies[i]);
+      }
+
+  /* If it's real...  */
+  if (LDSYMLEN (pst))
+    {
+      /* Init stuff necessary for reading in symbols */
+      buildsym_init ();
+      old_chain = make_cleanup (really_free_pendings, 0);
+
+      pst->symtab =
+       hpread_expand_symtab (pst->objfile, LDSYMOFF (pst), LDSYMLEN (pst),
+                             pst->textlow, pst->texthigh - pst->textlow,
+                             pst->section_offsets, pst->filename);
+      sort_symtab_syms (pst->symtab);
+
+      do_cleanups (old_chain);
+    }
+
+  pst->readin = 1;
+}
+
+/* Read in all of the symbols for a given psymtab for real.
+   Be verbose about it if the user wants that.  */
+
+void
+hpread_psymtab_to_symtab (struct partial_symtab *pst)
+{
+  /* Get out quick if given junk.  */
+  if (!pst)
+    return;
+
+  /* Sanity check.  */
+  if (pst->readin)
+    {
+      fprintf_unfiltered (gdb_stderr, "Psymtab for %s already read in."
+                         "  Shouldn't happen.\n",
+                         pst->filename);
+      return;
+    }
+
+  /* elz: setting the flag to indicate that the code of the target
+     was compiled using an HP compiler (aCC, cc) 
+     the processing_acc_compilation variable is declared in the 
+     file buildsym.h, the HP_COMPILED_TARGET is defined to be equal
+     to 3 in the file tm_hppa.h */
+
+  processing_gcc_compilation = 0;
+
+  if (LDSYMLEN (pst) || pst->number_of_dependencies)
+    {
+      /* Print the message now, before reading the string table,
+         to avoid disconcerting pauses.  */
+      if (info_verbose)
+       {
+         printf_filtered ("Reading in symbols for %s...", pst->filename);
+         gdb_flush (gdb_stdout);
+       }
+
+      hpread_psymtab_to_symtab_1 (pst);
+
+      /* Match with global symbols.  This only needs to be done once,
+         after all of the symtabs and dependencies have been read in.   */
+      scan_file_globals (pst->objfile);
+
+      /* Finish up the debug error message.  */
+      if (info_verbose)
+       printf_filtered ("done.\n");
+    }
+}
+
+/* Read in a defined section of a specific object file's symbols.
+
+   DESC is the file descriptor for the file, positioned at the
+   beginning of the symtab
+   SYM_OFFSET is the offset within the file of
+   the beginning of the symbols we want to read
+   SYM_SIZE is the size of the symbol info to read in.
+   TEXT_OFFSET is the beginning of the text segment we are reading symbols for
+   TEXT_SIZE is the size of the text segment read in.
+   SECTION_OFFSETS are the relocation offsets which get added to each symbol. */
+
+static struct symtab *
+hpread_expand_symtab (struct objfile *objfile, int sym_offset, int sym_size,
+                     CORE_ADDR text_offset, int text_size,
+                     struct section_offsets *section_offsets, char *filename)
+{
+  char *namestring;
+  union dnttentry *dn_bufp;
+  unsigned max_symnum;
+  int at_module_boundary = 0;
+  /* 1 => at end, -1 => at beginning */
+
+  int sym_index = sym_offset / sizeof (struct dntt_type_block);
+
+  current_objfile = objfile;
+  subfile_stack = 0;
+
+  last_source_file = 0;
+
+  /* Demangling style -- if EDG style already set, don't change it,
+     as HP style causes some problems with the KAI EDG compiler */
+  if (current_demangling_style != edg_demangling)
+    {
+      /* Otherwise, ensure that we are using HP style demangling */
+      set_demangling_style (HP_DEMANGLING_STYLE_STRING);
+    }
+
+  dn_bufp = hpread_get_lntt (sym_index, objfile);
+  if (!((dn_bufp->dblock.kind == (unsigned char) DNTT_TYPE_SRCFILE) ||
+       (dn_bufp->dblock.kind == (unsigned char) DNTT_TYPE_MODULE)))
+    {
+      start_symtab ("globals", NULL, 0);
+      record_debugformat ("HP");
+    }
+
+  /* The psymtab builder (hp-psymtab-read.c) is the one that
+   * determined the "sym_size" argument (i.e. how many DNTT symbols
+   * are in this symtab), which we use to compute "max_symnum"
+   * (point in DNTT to which we read). 
+   *
+   * Perhaps this should be changed so that 
+   * process_one_debug_symbol() "knows" when
+   * to stop reading (based on reading from the MODULE to the matching
+   * END), and take out this reliance on a #-syms being passed in...
+   * (I'm worried about the reliability of this number). But I'll
+   * leave it as-is, for now. - RT
+   *
+   * The change above has been made. I've left the "for" loop control
+   * in to prepare for backing this out again. -JB
+   */
+  max_symnum = sym_size / sizeof (struct dntt_type_block);
+  /* No reason to multiply on pst side and divide on sym side... FIXME */
+
+  /* Read in and process each debug symbol within the specified range.
+   */
+  for (symnum = 0;
+       symnum < max_symnum;
+       symnum++)
+    {
+      QUIT;                    /* Allow this to be interruptable */
+      dn_bufp = hpread_get_lntt (sym_index + symnum, objfile);
+
+      if (dn_bufp->dblock.extension)
+       continue;
+
+      /* Yow!  We call SET_NAMESTRING on things without names!  */
+      SET_NAMESTRING (dn_bufp, &namestring, objfile);
+
+      hpread_process_one_debug_symbol (dn_bufp, namestring, section_offsets,
+                                      objfile, text_offset, text_size,
+                                      filename, symnum + sym_index,
+                                      &at_module_boundary
+       );
+
+      /* OLD COMMENTS: This routine is only called for psts.  All psts
+       * correspond to MODULES.  If we ever do lazy-reading of globals
+       * from the LNTT, then there will be a pst which ends when the
+       * LNTT ends, and not at an END MODULE entry.  Then we'll have
+       * to re-visit this break.  
+
+       if( at_end_of_module )
+       break;
+
+       */
+
+      /* We no longer break out of the loop when we reach the end of a
+         module. The reason is that with CTTI, the compiler can generate
+         function symbols (for template function instantiations) which are not
+         in any module; typically they show up beyond a module's end, and
+         before the next module's start.  We include them in the current
+         module.  However, we still don't trust the MAX_SYMNUM value from
+         the psymtab, so we break out if we enter a new module. */
+
+      if (at_module_boundary == -1)
+       break;
+    }
+
+  current_objfile = NULL;
+  hp_som_som_object_present = 1;       /* Indicate we've processed an HP SOM SOM file */
+
+  return end_symtab (text_offset + text_size, objfile, SECT_OFF_TEXT (objfile));
+}
+\f
+
+
+
+/* Convert basic types from HP debug format into GDB internal format.  */
+
+static int
+hpread_type_translate (dnttpointer typep)
+{
+  if (!typep.dntti.immediate)
+    {
+      error ("error in hpread_type_translate\n.");
+      return FT_VOID;
+    }
+
+  switch (typep.dntti.type)
+    {
+    case HP_TYPE_BOOLEAN:
+    case HP_TYPE_BOOLEAN_S300_COMPAT:
+    case HP_TYPE_BOOLEAN_VAX_COMPAT:
+      return FT_BOOLEAN;
+    case HP_TYPE_CHAR:         /* C signed char, C++ plain char */
+
+    case HP_TYPE_WIDE_CHAR:
+      return FT_CHAR;
+    case HP_TYPE_INT:
+      if (typep.dntti.bitlength <= 8)
+       return FT_SIGNED_CHAR;  /* C++ signed char */
+      if (typep.dntti.bitlength <= 16)
+       return FT_SHORT;
+      if (typep.dntti.bitlength <= 32)
+       return FT_INTEGER;
+      return FT_LONG_LONG;
+    case HP_TYPE_LONG:
+      if (typep.dntti.bitlength <= 8)
+       return FT_SIGNED_CHAR;  /* C++ signed char. */
+      return FT_LONG;
+    case HP_TYPE_UNSIGNED_LONG:
+      if (typep.dntti.bitlength <= 8)
+       return FT_UNSIGNED_CHAR;        /* C/C++ unsigned char */
+      if (typep.dntti.bitlength <= 16)
+       return FT_UNSIGNED_SHORT;
+      if (typep.dntti.bitlength <= 32)
+       return FT_UNSIGNED_LONG;
+      return FT_UNSIGNED_LONG_LONG;
+    case HP_TYPE_UNSIGNED_INT:
+      if (typep.dntti.bitlength <= 8)
+       return FT_UNSIGNED_CHAR;
+      if (typep.dntti.bitlength <= 16)
+       return FT_UNSIGNED_SHORT;
+      if (typep.dntti.bitlength <= 32)
+       return FT_UNSIGNED_INTEGER;
+      return FT_UNSIGNED_LONG_LONG;
+    case HP_TYPE_REAL:
+    case HP_TYPE_REAL_3000:
+    case HP_TYPE_DOUBLE:
+      if (typep.dntti.bitlength == 64)
+       return FT_DBL_PREC_FLOAT;
+      if (typep.dntti.bitlength == 128)
+       return FT_EXT_PREC_FLOAT;
+      return FT_FLOAT;
+    case HP_TYPE_COMPLEX:
+    case HP_TYPE_COMPLEXS3000:
+      if (typep.dntti.bitlength == 128)
+       return FT_DBL_PREC_COMPLEX;
+      if (typep.dntti.bitlength == 192)
+       return FT_EXT_PREC_COMPLEX;
+      return FT_COMPLEX;
+    case HP_TYPE_VOID:
+      return FT_VOID;
+    case HP_TYPE_STRING200:
+    case HP_TYPE_LONGSTRING200:
+    case HP_TYPE_FTN_STRING_SPEC:
+    case HP_TYPE_MOD_STRING_SPEC:
+    case HP_TYPE_MOD_STRING_3000:
+    case HP_TYPE_FTN_STRING_S300_COMPAT:
+    case HP_TYPE_FTN_STRING_VAX_COMPAT:
+      return FT_STRING;
+    case HP_TYPE_TEMPLATE_ARG:
+      return FT_TEMPLATE_ARG;
+    case HP_TYPE_TEXT:
+    case HP_TYPE_FLABEL:
+    case HP_TYPE_PACKED_DECIMAL:
+    case HP_TYPE_ANYPOINTER:
+    case HP_TYPE_GLOBAL_ANYPOINTER:
+    case HP_TYPE_LOCAL_ANYPOINTER:
+    default:
+      warning ("hpread_type_translate: unhandled type code.\n");
+      return FT_VOID;
+    }
+}
+
+/* Given a position in the DNTT, return a pointer to the 
+ * already-built "struct type" (if any), for the type defined 
+ * at that position.
+ */
+
+static struct type **
+hpread_lookup_type (dnttpointer hp_type, struct objfile *objfile)
+{
+  unsigned old_len;
+  int index = hp_type.dnttp.index;
+  int size_changed = 0;
+
+  /* The immediate flag indicates this doesn't actually point to
+   * a type DNTT.
+   */
+  if (hp_type.dntti.immediate)
+    return NULL;
+
+  /* For each objfile, we maintain a "type vector".
+   * This an array of "struct type *"'s with one pointer per DNTT index.
+   * Given a DNTT index, we look in this array to see if we have
+   * already processed this DNTT and if it is a type definition.
+   * If so, then we can locate a pointer to the already-built
+   * "struct type", and not build it again.
+   * 
+   * The need for this arises because our DNTT-walking code wanders
+   * around. In particular, it will encounter the same type multiple
+   * times (once for each object of that type). We don't want to 
+   * built multiple "struct type"'s for the same thing.
+   *
+   * Having said this, I should point out that this type-vector is
+   * an expensive way to keep track of this. If most DNTT entries are 
+   * 3 words, the type-vector will be 1/3 the size of the DNTT itself.
+   * Alternative solutions:
+   * - Keep a compressed or hashed table. Less memory, but more expensive
+   *   to search and update.
+   * - (Suggested by JB): Overwrite the DNTT entry itself
+   *   with the info. Create a new type code "ALREADY_BUILT", and modify
+   *   the DNTT to have that type code and point to the already-built entry.
+   * -RT
+   */
+
+  if (index < LNTT_SYMCOUNT (objfile))
+    {
+      if (index >= DNTT_TYPE_VECTOR_LENGTH (objfile))
+       {
+         old_len = DNTT_TYPE_VECTOR_LENGTH (objfile);
+
+         /* See if we need to allocate a type-vector. */
+         if (old_len == 0)
+           {
+             DNTT_TYPE_VECTOR_LENGTH (objfile) = LNTT_SYMCOUNT (objfile) + GNTT_SYMCOUNT (objfile);
+             DNTT_TYPE_VECTOR (objfile) = (struct type **)
+               xmmalloc (objfile->md, DNTT_TYPE_VECTOR_LENGTH (objfile) * sizeof (struct type *));
+             memset (&DNTT_TYPE_VECTOR (objfile)[old_len], 0,
+                     (DNTT_TYPE_VECTOR_LENGTH (objfile) - old_len) *
+                     sizeof (struct type *));
+           }
+
+         /* See if we need to resize type-vector. With my change to
+          * initially allocate a correct-size type-vector, this code
+          * should no longer trigger.
+          */
+         while (index >= DNTT_TYPE_VECTOR_LENGTH (objfile))
+           {
+             DNTT_TYPE_VECTOR_LENGTH (objfile) *= 2;
+             size_changed = 1;
+           }
+         if (size_changed)
+           {
+             DNTT_TYPE_VECTOR (objfile) = (struct type **)
+               xmrealloc (objfile->md,
+                          (char *) DNTT_TYPE_VECTOR (objfile),
+                  (DNTT_TYPE_VECTOR_LENGTH (objfile) * sizeof (struct type *)));
+
+             memset (&DNTT_TYPE_VECTOR (objfile)[old_len], 0,
+                     (DNTT_TYPE_VECTOR_LENGTH (objfile) - old_len) *
+                     sizeof (struct type *));
+           }
+
+       }
+      return &DNTT_TYPE_VECTOR (objfile)[index];
+    }
+  else
+    return NULL;
+}
+
+/* Possibly allocate a GDB internal type so we can internalize HP_TYPE.
+   Note we'll just return the address of a GDB internal type if we already
+   have it lying around.  */
+
+static struct type *
+hpread_alloc_type (dnttpointer hp_type, struct objfile *objfile)
+{
+  struct type **type_addr;
+
+  type_addr = hpread_lookup_type (hp_type, objfile);
+  if (*type_addr == 0)
+    {
+      *type_addr = alloc_type (objfile);
+
+      /* A hack - if we really are a C++ class symbol, then this default
+       * will get overriden later on.
+       */
+      TYPE_CPLUS_SPECIFIC (*type_addr)
+       = (struct cplus_struct_type *) &cplus_struct_default;
+    }
+
+  return *type_addr;
+}
+
+/* Read a native enumerated type and return it in GDB internal form.  */
+
+static struct type *
+hpread_read_enum_type (dnttpointer hp_type, union dnttentry *dn_bufp,
+                      struct objfile *objfile)
+{
+  struct type *type;
+  struct pending **symlist, *osyms, *syms;
+  struct pending *local_list = NULL;
+  int o_nsyms, nsyms = 0;
+  dnttpointer mem;
+  union dnttentry *memp;
+  char *name;
+  long n;
+  struct symbol *sym;
+
+  /* Allocate a GDB type. If we've already read in this enum type,
+   * it'll return the already built GDB type, so stop here.
+   * (Note: I added this check, to conform with what's done for 
+   *  struct, union, class.
+   *  I assume this is OK. - RT)
+   */
+  type = hpread_alloc_type (hp_type, objfile);
+  if (TYPE_CODE (type) == TYPE_CODE_ENUM)
+    return type;
+
+  /* HP C supports "sized enums", where a specifier such as "short" or
+     "char" can be used to get enums of different sizes. So don't assume
+     an enum is always 4 bytes long. pai/1997-08-21 */
+  TYPE_LENGTH (type) = dn_bufp->denum.bitlength / 8;
+
+  symlist = &file_symbols;
+  osyms = *symlist;
+  o_nsyms = osyms ? osyms->nsyms : 0;
+
+  /* Get a name for each member and add it to our list of members.  
+   * The list of "mem" SOM records we are walking should all be
+   * SOM type DNTT_TYPE_MEMENUM (not checked).
+   */
+  mem = dn_bufp->denum.firstmem;
+  while (mem.word && mem.word != DNTTNIL)
+    {
+      memp = hpread_get_lntt (mem.dnttp.index, objfile);
+
+      name = VT (objfile) + memp->dmember.name;
+      sym = (struct symbol *) obstack_alloc (&objfile->symbol_obstack,
+                                            sizeof (struct symbol));
+      memset (sym, 0, sizeof (struct symbol));
+      SYMBOL_NAME (sym) = obsavestring (name, strlen (name),
+                                       &objfile->symbol_obstack);
+      SYMBOL_CLASS (sym) = LOC_CONST;
+      SYMBOL_NAMESPACE (sym) = VAR_NAMESPACE;
+      SYMBOL_VALUE (sym) = memp->dmember.value;
+      add_symbol_to_list (sym, symlist);
+      nsyms++;
+      mem = memp->dmember.nextmem;
+    }
+
+  /* Now that we know more about the enum, fill in more info.  */
+  TYPE_CODE (type) = TYPE_CODE_ENUM;
+  TYPE_FLAGS (type) &= ~TYPE_FLAG_STUB;
+  TYPE_NFIELDS (type) = nsyms;
+  TYPE_FIELDS (type) = (struct field *)
+    obstack_alloc (&objfile->type_obstack, sizeof (struct field) * nsyms);
+
+  /* Find the symbols for the members and put them into the type.
+     The symbols can be found in the symlist that we put them on
+     to cause them to be defined.  osyms contains the old value
+     of that symlist; everything up to there was defined by us.
+
+     Note that we preserve the order of the enum constants, so
+     that in something like "enum {FOO, LAST_THING=FOO}" we print
+     FOO, not LAST_THING.  */
+  for (syms = *symlist, n = 0; syms; syms = syms->next)
+    {
+      int j = 0;
+      if (syms == osyms)
+       j = o_nsyms;
+      for (; j < syms->nsyms; j++, n++)
+       {
+         struct symbol *xsym = syms->symbol[j];
+         SYMBOL_TYPE (xsym) = type;
+         TYPE_FIELD_NAME (type, n) = SYMBOL_NAME (xsym);
+         TYPE_FIELD_BITPOS (type, n) = SYMBOL_VALUE (xsym);
+         TYPE_FIELD_BITSIZE (type, n) = 0;
+       }
+      if (syms == osyms)
+       break;
+    }
+
+  return type;
+}
+
+/* Read and internalize a native function debug symbol.  */
+
+static struct type *
+hpread_read_function_type (dnttpointer hp_type, union dnttentry *dn_bufp,
+                          struct objfile *objfile, int newblock)
+{
+  struct type *type, *type1;
+  struct pending *syms;
+  struct pending *local_list = NULL;
+  int nsyms = 0;
+  dnttpointer param;
+  union dnttentry *paramp;
+  char *name;
+  long n;
+  struct symbol *sym;
+  int record_args = 1;
+
+  /* See if we've already read in this type.  */
+  type = hpread_alloc_type (hp_type, objfile);
+  if (TYPE_CODE (type) == TYPE_CODE_FUNC)
+    {
+      record_args = 0;         /* already read in, don't modify type */
+    }
+  else
+    {
+      /* Nope, so read it in and store it away.  */
+      if (dn_bufp->dblock.kind == DNTT_TYPE_FUNCTION ||
+         dn_bufp->dblock.kind == DNTT_TYPE_MEMFUNC)
+       type1 = lookup_function_type (hpread_type_lookup (dn_bufp->dfunc.retval,
+                                                         objfile));
+      else if (dn_bufp->dblock.kind == DNTT_TYPE_FUNCTYPE)
+       type1 = lookup_function_type (hpread_type_lookup (dn_bufp->dfunctype.retval,
+                                                         objfile));
+      else                     /* expect DNTT_TYPE_FUNC_TEMPLATE */
+       type1 = lookup_function_type (hpread_type_lookup (dn_bufp->dfunc_template.retval,
+                                                         objfile));
+      replace_type (type, type1);
+
+      /* Mark it -- in the middle of processing */
+      TYPE_FLAGS (type) |= TYPE_FLAG_INCOMPLETE;
+    }
+
+  /* Now examine each parameter noting its type, location, and a
+     wealth of other information.  */
+  if (dn_bufp->dblock.kind == DNTT_TYPE_FUNCTION ||
+      dn_bufp->dblock.kind == DNTT_TYPE_MEMFUNC)
+    param = dn_bufp->dfunc.firstparam;
+  else if (dn_bufp->dblock.kind == DNTT_TYPE_FUNCTYPE)
+    param = dn_bufp->dfunctype.firstparam;
+  else                         /* expect DNTT_TYPE_FUNC_TEMPLATE */
+    param = dn_bufp->dfunc_template.firstparam;
+  while (param.word && param.word != DNTTNIL)
+    {
+      paramp = hpread_get_lntt (param.dnttp.index, objfile);
+      nsyms++;
+      param = paramp->dfparam.nextparam;
+
+      /* Get the name.  */
+      name = VT (objfile) + paramp->dfparam.name;
+      sym = (struct symbol *) obstack_alloc (&objfile->symbol_obstack,
+                                            sizeof (struct symbol));
+      (void) memset (sym, 0, sizeof (struct symbol));
+      SYMBOL_NAME (sym) = obsavestring (name, strlen (name),
+                                       &objfile->symbol_obstack);
+
+      /* Figure out where it lives.  */
+      if (paramp->dfparam.regparam)
+       SYMBOL_CLASS (sym) = LOC_REGPARM;
+      else if (paramp->dfparam.indirect)
+       SYMBOL_CLASS (sym) = LOC_REF_ARG;
+      else
+       SYMBOL_CLASS (sym) = LOC_ARG;
+      SYMBOL_NAMESPACE (sym) = VAR_NAMESPACE;
+      if (paramp->dfparam.copyparam)
+       {
+         SYMBOL_VALUE (sym) = paramp->dfparam.location;
+#ifdef HPREAD_ADJUST_STACK_ADDRESS
+         SYMBOL_VALUE (sym)
+           += HPREAD_ADJUST_STACK_ADDRESS (CURRENT_FUNCTION_VALUE (objfile));
+#endif
+         /* This is likely a pass-by-invisible reference parameter,
+            Hack on the symbol class to make GDB happy.  */
+         /* ??rehrauer: This appears to be broken w/r/t to passing
+            C values of type float and struct.  Perhaps this ought
+            to be highighted as a special case, but for now, just
+            allowing these to be LOC_ARGs seems to work fine.
+          */
+#if 0
+         SYMBOL_CLASS (sym) = LOC_REGPARM_ADDR;
+#endif
+       }
+      else
+       SYMBOL_VALUE (sym) = paramp->dfparam.location;
+
+      /* Get its type.  */
+      SYMBOL_TYPE (sym) = hpread_type_lookup (paramp->dfparam.type, objfile);
+      /* Add it to the symbol list.  */
+      /* Note 1 (RT) At the moment, add_symbol_to_list() is also being
+       * called on FPARAM symbols from the process_one_debug_symbol()
+       * level... so parameters are getting added twice! (this shows
+       * up in the symbol dump you get from "maint print symbols ...").
+       * Note 2 (RT) I took out the processing of FPARAM from the 
+       * process_one_debug_symbol() level, so at the moment parameters are only
+       * being processed here. This seems to have no ill effect.
+       */
+      /* Note 3 (pai/1997-08-11) I removed the add_symbol_to_list() which put
+         each fparam on the local_symbols list from here.  Now we use the
+         local_list to which fparams are added below, and set the param_symbols
+         global to point to that at the end of this routine. */
+      /* elz: I added this new list of symbols which is local to the function.
+         this list is the one which is actually used to build the type for the
+         function rather than the gloabal list pointed to by symlist.
+         Using a global list to keep track of the parameters is wrong, because 
+         this function is called recursively if one parameter happend to be
+         a function itself with more parameters in it. Adding parameters to the
+         same global symbol list would not work!      
+         Actually it did work in case of cc compiled programs where you do 
+         not check the parameter lists of the arguments. */
+      add_symbol_to_list (sym, &local_list);
+
+    }
+
+  /* If type was read in earlier, don't bother with modifying
+     the type struct */
+  if (!record_args)
+    goto finish;
+
+  /* Note how many parameters we found.  */
+  TYPE_NFIELDS (type) = nsyms;
+  TYPE_FIELDS (type) = (struct field *)
+    obstack_alloc (&objfile->type_obstack,
+                  sizeof (struct field) * nsyms);
+
+  /* Find the symbols for the parameters and 
+     use them to fill parameter-type information into the function-type.
+     The parameter symbols can be found in the local_list that we just put them on. */
+  /* Note that we preserve the order of the parameters, so
+     that in something like "enum {FOO, LAST_THING=FOO}" we print
+     FOO, not LAST_THING.  */
+
+  /* get the parameters types from the local list not the global list
+     so that the type can be correctly constructed for functions which
+     have function as parameters */
+  for (syms = local_list, n = 0; syms; syms = syms->next)
+    {
+      int j = 0;
+      for (j = 0; j < syms->nsyms; j++, n++)
+       {
+         struct symbol *xsym = syms->symbol[j];
+         TYPE_FIELD_NAME (type, n) = SYMBOL_NAME (xsym);
+         TYPE_FIELD_TYPE (type, n) = SYMBOL_TYPE (xsym);
+         TYPE_FIELD_ARTIFICIAL (type, n) = 0;
+         TYPE_FIELD_BITSIZE (type, n) = 0;
+       }
+    }
+  /* Mark it as having been processed */
+  TYPE_FLAGS (type) &= ~(TYPE_FLAG_INCOMPLETE);
+
+  /* Check whether we need to fix-up a class type with this function's type */
+  if (fixup_class && (fixup_method == type))
+    {
+      fixup_class_method_type (fixup_class, fixup_method, objfile);
+      fixup_class = NULL;
+      fixup_method = NULL;
+    }
+
+  /* Set the param list of this level of the context stack
+     to our local list.  Do this only if this function was
+     called for creating a new block, and not if it was called
+     simply to get the function type. This prevents recursive
+     invocations from trashing param_symbols. */
+finish:
+  if (newblock)
+    param_symbols = local_list;
+
+  return type;
+}
+
+
+/* Read and internalize a native DOC function debug symbol.  */
+/* This is almost identical to hpread_read_function_type(), except
+ * for references to dn_bufp->ddocfunc instead of db_bufp->dfunc.
+ * Since debug information for DOC functions is more likely to be
+ * volatile, please leave it this way.
+ */
+static struct type *
+hpread_read_doc_function_type (dnttpointer hp_type, union dnttentry *dn_bufp,
+                              struct objfile *objfile, int newblock)
+{
+  struct type *type, *type1;
+  struct pending *syms;
+  struct pending *local_list = NULL;
+  int nsyms = 0;
+  dnttpointer param;
+  union dnttentry *paramp;
+  char *name;
+  long n;
+  struct symbol *sym;
+  int record_args = 1;
+
+  /* See if we've already read in this type.  */
+  type = hpread_alloc_type (hp_type, objfile);
+  if (TYPE_CODE (type) == TYPE_CODE_FUNC)
+    {
+      record_args = 0;         /* already read in, don't modify type */
+    }
+  else
+    {
+      /* Nope, so read it in and store it away.  */
+      if (dn_bufp->dblock.kind == DNTT_TYPE_DOC_FUNCTION ||
+         dn_bufp->dblock.kind == DNTT_TYPE_DOC_MEMFUNC)
+       type1 = lookup_function_type (hpread_type_lookup (dn_bufp->ddocfunc.retval,
+                                                         objfile));
+      replace_type (type, type1);
+
+      /* Mark it -- in the middle of processing */
+      TYPE_FLAGS (type) |= TYPE_FLAG_INCOMPLETE;
+    }
+
+  /* Now examine each parameter noting its type, location, and a
+     wealth of other information.  */
+  if (dn_bufp->dblock.kind == DNTT_TYPE_DOC_FUNCTION ||
+      dn_bufp->dblock.kind == DNTT_TYPE_DOC_MEMFUNC)
+    param = dn_bufp->ddocfunc.firstparam;
+  while (param.word && param.word != DNTTNIL)
+    {
+      paramp = hpread_get_lntt (param.dnttp.index, objfile);
+      nsyms++;
+      param = paramp->dfparam.nextparam;
+
+      /* Get the name.  */
+      name = VT (objfile) + paramp->dfparam.name;
+      sym = (struct symbol *) obstack_alloc (&objfile->symbol_obstack,
+                                            sizeof (struct symbol));
+      (void) memset (sym, 0, sizeof (struct symbol));
+      SYMBOL_NAME (sym) = name;
+
+      /* Figure out where it lives.  */
+      if (paramp->dfparam.regparam)
+       SYMBOL_CLASS (sym) = LOC_REGPARM;
+      else if (paramp->dfparam.indirect)
+       SYMBOL_CLASS (sym) = LOC_REF_ARG;
+      else
+       SYMBOL_CLASS (sym) = LOC_ARG;
+      SYMBOL_NAMESPACE (sym) = VAR_NAMESPACE;
+      if (paramp->dfparam.copyparam)
+       {
+         SYMBOL_VALUE (sym) = paramp->dfparam.location;
+#ifdef HPREAD_ADJUST_STACK_ADDRESS
+         SYMBOL_VALUE (sym)
+           += HPREAD_ADJUST_STACK_ADDRESS (CURRENT_FUNCTION_VALUE (objfile));
+#endif
+         /* This is likely a pass-by-invisible reference parameter,
+            Hack on the symbol class to make GDB happy.  */
+         /* ??rehrauer: This appears to be broken w/r/t to passing
+            C values of type float and struct.  Perhaps this ought
+            to be highighted as a special case, but for now, just
+            allowing these to be LOC_ARGs seems to work fine.
+          */
+#if 0
+         SYMBOL_CLASS (sym) = LOC_REGPARM_ADDR;
+#endif
+       }
+      else
+       SYMBOL_VALUE (sym) = paramp->dfparam.location;
+
+      /* Get its type.  */
+      SYMBOL_TYPE (sym) = hpread_type_lookup (paramp->dfparam.type, objfile);
+      /* Add it to the symbol list.  */
+      /* Note 1 (RT) At the moment, add_symbol_to_list() is also being
+       * called on FPARAM symbols from the process_one_debug_symbol()
+       * level... so parameters are getting added twice! (this shows
+       * up in the symbol dump you get from "maint print symbols ...").
+       * Note 2 (RT) I took out the processing of FPARAM from the 
+       * process_one_debug_symbol() level, so at the moment parameters are only
+       * being processed here. This seems to have no ill effect.
+       */
+      /* Note 3 (pai/1997-08-11) I removed the add_symbol_to_list() which put
+         each fparam on the local_symbols list from here.  Now we use the
+         local_list to which fparams are added below, and set the param_symbols
+         global to point to that at the end of this routine. */
+
+      /* elz: I added this new list of symbols which is local to the function.
+         this list is the one which is actually used to build the type for the
+         function rather than the gloabal list pointed to by symlist.
+         Using a global list to keep track of the parameters is wrong, because 
+         this function is called recursively if one parameter happend to be
+         a function itself with more parameters in it. Adding parameters to the
+         same global symbol list would not work!      
+         Actually it did work in case of cc compiled programs where you do not check the
+         parameter lists of the arguments.  */
+      add_symbol_to_list (sym, &local_list);
+    }
+
+  /* If type was read in earlier, don't bother with modifying
+     the type struct */
+  if (!record_args)
+    goto finish;
+
+  /* Note how many parameters we found.  */
+  TYPE_NFIELDS (type) = nsyms;
+  TYPE_FIELDS (type) = (struct field *)
+    obstack_alloc (&objfile->type_obstack,
+                  sizeof (struct field) * nsyms);
+
+  /* Find the symbols for the parameters and 
+     use them to fill parameter-type information into the function-type.
+     The parameter symbols can be found in the local_list that we just put them on. */
+  /* Note that we preserve the order of the parameters, so
+     that in something like "enum {FOO, LAST_THING=FOO}" we print
+     FOO, not LAST_THING.  */
+
+  /* get the parameters types from the local list not the global list
+     so that the type can be correctly constructed for functions which
+     have function as parameters
+   */
+  for (syms = local_list, n = 0; syms; syms = syms->next)
+    {
+      int j = 0;
+      for (j = 0; j < syms->nsyms; j++, n++)
+       {
+         struct symbol *xsym = syms->symbol[j];
+         TYPE_FIELD_NAME (type, n) = SYMBOL_NAME (xsym);
+         TYPE_FIELD_TYPE (type, n) = SYMBOL_TYPE (xsym);
+         TYPE_FIELD_ARTIFICIAL (type, n) = 0;
+         TYPE_FIELD_BITSIZE (type, n) = 0;
+       }
+    }
+
+  /* Mark it as having been processed */
+  TYPE_FLAGS (type) &= ~(TYPE_FLAG_INCOMPLETE);
+
+  /* Check whether we need to fix-up a class type with this function's type */
+  if (fixup_class && (fixup_method == type))
+    {
+      fixup_class_method_type (fixup_class, fixup_method, objfile);
+      fixup_class = NULL;
+      fixup_method = NULL;
+    }
+
+  /* Set the param list of this level of the context stack
+     to our local list.  Do this only if this function was
+     called for creating a new block, and not if it was called
+     simply to get the function type. This prevents recursive
+     invocations from trashing param_symbols. */
+finish:
+  if (newblock)
+    param_symbols = local_list;
+
+  return type;
+}
+
+
+
+/* A file-level variable which keeps track of the current-template
+ * being processed. Set in hpread_read_struct_type() while processing
+ * a template type. Referred to in hpread_get_nth_templ_arg().
+ * Yes, this is a kludge, but it arises from the kludge that already
+ * exists in symtab.h, namely the fact that they encode
+ * "template argument n" with fundamental type FT_TEMPLATE_ARG and
+ * bitlength n. This means that deep in processing fundamental types
+ * I need to ask the question "what template am I in the middle of?".
+ * The alternative to stuffing a global would be to pass an argument
+ * down the chain of calls just for this purpose.
+ * 
+ * There may be problems handling nested templates... tough.
+ */
+static struct type *current_template = NULL;
+
+/* Read in and internalize a structure definition.  
+ * This same routine is called for struct, union, and class types.
+ * Also called for templates, since they build a very similar
+ * type entry as for class types.
+ */
+
+static struct type *
+hpread_read_struct_type (dnttpointer hp_type, union dnttentry *dn_bufp,
+                        struct objfile *objfile)
+{
+  /* The data members get linked together into a list of struct nextfield's */
+  struct nextfield
+    {
+      struct nextfield *next;
+      struct field field;
+      unsigned char attributes;        /* store visibility and virtuality info */
+#define ATTR_VIRTUAL 1
+#define ATTR_PRIVATE 2
+#define ATTR_PROTECT 3
+    };
+
+
+  /* The methods get linked together into a list of struct next_fn_field's */
+  struct next_fn_field
+    {
+      struct next_fn_field *next;
+      struct fn_fieldlist field;
+      struct fn_field fn_field;
+      int num_fn_fields;
+    };
+
+  /* The template args get linked together into a list of struct next_template's */
+  struct next_template
+    {
+      struct next_template *next;
+      struct template_arg arg;
+    };
+
+  /* The template instantiations get linked together into a list of these... */
+  struct next_instantiation
+    {
+      struct next_instantiation *next;
+      struct type *t;
+    };
+
+  struct type *type;
+  struct type *baseclass;
+  struct type *memtype;
+  struct nextfield *list = 0, *tmp_list = 0;
+  struct next_fn_field *fn_list = 0;
+  struct next_fn_field *fn_p;
+  struct next_template *t_new, *t_list = 0;
+  struct nextfield *new;
+  struct next_fn_field *fn_new;
+  struct next_instantiation *i_new, *i_list = 0;
+  int n, nfields = 0, n_fn_fields = 0, n_fn_fields_total = 0;
+  int n_base_classes = 0, n_templ_args = 0;
+  int ninstantiations = 0;
+  dnttpointer field, fn_field, parent;
+  union dnttentry *fieldp, *fn_fieldp, *parentp;
+  int i;
+  int static_member = 0;
+  int const_member = 0;
+  int volatile_member = 0;
+  unsigned long vtbl_offset;
+  int need_bitvectors = 0;
+  char *method_name = NULL;
+  char *method_alias = NULL;
+
+
+  /* Is it something we've already dealt with?  */
+  type = hpread_alloc_type (hp_type, objfile);
+  if ((TYPE_CODE (type) == TYPE_CODE_STRUCT) ||
+      (TYPE_CODE (type) == TYPE_CODE_UNION) ||
+      (TYPE_CODE (type) == TYPE_CODE_CLASS) ||
+      (TYPE_CODE (type) == TYPE_CODE_TEMPLATE))
+    return type;
+
+  /* Get the basic type correct.  */
+  if (dn_bufp->dblock.kind == DNTT_TYPE_STRUCT)
+    {
+      TYPE_CODE (type) = TYPE_CODE_STRUCT;
+      TYPE_LENGTH (type) = dn_bufp->dstruct.bitlength / 8;
+    }
+  else if (dn_bufp->dblock.kind == DNTT_TYPE_UNION)
+    {
+      TYPE_CODE (type) = TYPE_CODE_UNION;
+      TYPE_LENGTH (type) = dn_bufp->dunion.bitlength / 8;
+    }
+  else if (dn_bufp->dblock.kind == DNTT_TYPE_CLASS)
+    {
+      TYPE_CODE (type) = TYPE_CODE_CLASS;
+      TYPE_LENGTH (type) = dn_bufp->dclass.bitlength / 8;
+
+      /* Overrides the TYPE_CPLUS_SPECIFIC(type) with allocated memory
+       * rather than &cplus_struct_default.
+       */
+      allocate_cplus_struct_type (type);
+
+      /* Fill in declared-type.
+       * (The C++ compiler will emit TYPE_CODE_CLASS 
+       * for all 3 of "class", "struct"
+       * "union", and we have to look at the "class_decl" field if we
+       * want to know how it was really declared)
+       */
+      /* (0==class, 1==union, 2==struct) */
+      TYPE_DECLARED_TYPE (type) = dn_bufp->dclass.class_decl;
+    }
+  else if (dn_bufp->dblock.kind == DNTT_TYPE_TEMPLATE)
+    {
+      /* Get the basic type correct.  */
+      TYPE_CODE (type) = TYPE_CODE_TEMPLATE;
+      allocate_cplus_struct_type (type);
+      TYPE_DECLARED_TYPE (type) = DECLARED_TYPE_TEMPLATE;
+    }
+  else
+    return type;
+
+
+  TYPE_FLAGS (type) &= ~TYPE_FLAG_STUB;
+
+  /* For classes, read the parent list.
+   * Question (RT): Do we need to do this for templates also?
+   */
+  if (dn_bufp->dblock.kind == DNTT_TYPE_CLASS)
+    {
+
+      /* First read the parent-list (classes from which we derive fields) */
+      parent = dn_bufp->dclass.parentlist;
+      while (parent.word && parent.word != DNTTNIL)
+       {
+         parentp = hpread_get_lntt (parent.dnttp.index, objfile);
+
+         /* "parentp" should point to a DNTT_TYPE_INHERITANCE record */
+
+         /* Get space to record the next field/data-member. */
+         new = (struct nextfield *) alloca (sizeof (struct nextfield));
+         new->next = list;
+         list = new;
+
+         FIELD_BITSIZE (list->field) = 0;
+
+         /* The "classname" field is actually a DNTT pointer to the base class */
+         baseclass = hpread_type_lookup (parentp->dinheritance.classname,
+                                         objfile);
+         FIELD_TYPE (list->field) = baseclass;
+
+         list->field.name = type_name_no_tag (FIELD_TYPE (list->field));
+
+         list->attributes = 0;
+
+         /* Check for virtuality of base, and set the
+          * offset of the base subobject within the object.
+          * (Offset set to -1 for virtual bases (for now).)
+          */
+         if (parentp->dinheritance.Virtual)
+           {
+             B_SET (&(list->attributes), ATTR_VIRTUAL);
+             parentp->dinheritance.offset = -1;
+           }
+         else
+           FIELD_BITPOS (list->field) = parentp->dinheritance.offset;
+
+         /* Check visibility */
+         switch (parentp->dinheritance.visibility)
+           {
+           case 1:
+             B_SET (&(list->attributes), ATTR_PROTECT);
+             break;
+           case 2:
+             B_SET (&(list->attributes), ATTR_PRIVATE);
+             break;
+           }
+
+         n_base_classes++;
+         nfields++;
+
+         parent = parentp->dinheritance.next;
+       }
+    }
+
+  /* For templates, read the template argument list.
+   * This must be done before processing the member list, because
+   * the member list may refer back to this. E.g.:
+   *   template <class T1, class T2> class q2 {
+   *     public:
+   *     T1 a;
+   *     T2 b;
+   *   };
+   * We need to read the argument list "T1", "T2" first.
+   */
+  if (dn_bufp->dblock.kind == DNTT_TYPE_TEMPLATE)
+    {
+      /* Kludge alert: This stuffs a global "current_template" which
+       * is referred to by hpread_get_nth_templ_arg(). The global
+       * is cleared at the end of this routine.
+       */
+      current_template = type;
+
+      /* Read in the argument list */
+      field = dn_bufp->dtemplate.arglist;
+      while (field.word && field.word != DNTTNIL)
+       {
+         /* Get this template argument */
+         fieldp = hpread_get_lntt (field.dnttp.index, objfile);
+         if (fieldp->dblock.kind != DNTT_TYPE_TEMPLATE_ARG)
+           {
+             warning ("Invalid debug info: Template argument entry is of wrong kind");
+             break;
+           }
+         /* Bump the count */
+         n_templ_args++;
+         /* Allocate and fill in a struct next_template */
+         t_new = (struct next_template *) alloca (sizeof (struct next_template));
+         t_new->next = t_list;
+         t_list = t_new;
+         t_list->arg.name = VT (objfile) + fieldp->dtempl_arg.name;
+         t_list->arg.type = hpread_read_templ_arg_type (field, fieldp,
+                                                objfile, t_list->arg.name);
+         /* Walk to the next template argument */
+         field = fieldp->dtempl_arg.nextarg;
+       }
+    }
+
+  TYPE_NTEMPLATE_ARGS (type) = n_templ_args;
+
+  if (n_templ_args > 0)
+    TYPE_TEMPLATE_ARGS (type) = (struct template_arg *)
+      obstack_alloc (&objfile->type_obstack, sizeof (struct template_arg) * n_templ_args);
+  for (n = n_templ_args; t_list; t_list = t_list->next)
+    {
+      n -= 1;
+      TYPE_TEMPLATE_ARG (type, n) = t_list->arg;
+    }
+
+  /* Next read in and internalize all the fields/members.  */
+  if (dn_bufp->dblock.kind == DNTT_TYPE_STRUCT)
+    field = dn_bufp->dstruct.firstfield;
+  else if (dn_bufp->dblock.kind == DNTT_TYPE_UNION)
+    field = dn_bufp->dunion.firstfield;
+  else if (dn_bufp->dblock.kind == DNTT_TYPE_CLASS)
+    field = dn_bufp->dclass.memberlist;
+  else if (dn_bufp->dblock.kind == DNTT_TYPE_TEMPLATE)
+    field = dn_bufp->dtemplate.memberlist;
+  else
+    field.word = DNTTNIL;
+
+  while (field.word && field.word != DNTTNIL)
+    {
+      fieldp = hpread_get_lntt (field.dnttp.index, objfile);
+
+      /* At this point "fieldp" may point to either a DNTT_TYPE_FIELD
+       * or a DNTT_TYPE_GENFIELD record. 
+       */
+      vtbl_offset = 0;
+      static_member = 0;
+      const_member = 0;
+      volatile_member = 0;
+
+      if (fieldp->dblock.kind == DNTT_TYPE_GENFIELD)
+       {
+
+         /* The type will be GENFIELD if the field is a method or
+          * a static member (or some other cases -- see below)
+          */
+
+         /* Follow a link to get to the record for the field. */
+         fn_field = fieldp->dgenfield.field;
+         fn_fieldp = hpread_get_lntt (fn_field.dnttp.index, objfile);
+
+         /* Virtual funcs are indicated by a VFUNC which points to the
+          * real entry
+          */
+         if (fn_fieldp->dblock.kind == DNTT_TYPE_VFUNC)
+           {
+             vtbl_offset = fn_fieldp->dvfunc.vtbl_offset;
+             fn_field = fn_fieldp->dvfunc.funcptr;
+             fn_fieldp = hpread_get_lntt (fn_field.dnttp.index, objfile);
+           }
+
+         /* A function's entry may be preceded by a modifier which
+          * labels it static/constant/volatile.
+          */
+         if (fn_fieldp->dblock.kind == DNTT_TYPE_MODIFIER)
+           {
+             static_member = fn_fieldp->dmodifier.m_static;
+             const_member = fn_fieldp->dmodifier.m_const;
+             volatile_member = fn_fieldp->dmodifier.m_volatile;
+             fn_field = fn_fieldp->dmodifier.type;
+             fn_fieldp = hpread_get_lntt (fn_field.dnttp.index, objfile);
+           }
+
+         /* Check whether we have a method */
+         if ((fn_fieldp->dblock.kind == DNTT_TYPE_MEMFUNC) ||
+             (fn_fieldp->dblock.kind == DNTT_TYPE_FUNCTION) ||
+             (fn_fieldp->dblock.kind == DNTT_TYPE_DOC_MEMFUNC) ||
+             (fn_fieldp->dblock.kind == DNTT_TYPE_DOC_FUNCTION))
+           {
+             /* Method found */
+
+             short ix = 0;
+
+             /* Look up function type of method */
+             memtype = hpread_type_lookup (fn_field, objfile);
+
+             /* Methods can be seen before classes in the SOM records.
+                If we are processing this class because it's a parameter of a
+                method, at this point the method's type is actually incomplete;
+                we'll have to fix it up later; mark the class for this. */
+
+             if (TYPE_INCOMPLETE (memtype))
+               {
+                 TYPE_FLAGS (type) |= TYPE_FLAG_INCOMPLETE;
+                 if (fixup_class)
+                   warning ("Two classes to fix up for method??  Type information may be incorrect for some classes.");
+                 if (fixup_method)
+                   warning ("Two methods to be fixed up at once?? Type information may be incorrect for some classes.");
+                 fixup_class = type;   /* remember this class has to be fixed up */
+                 fixup_method = memtype;       /* remember the method type to be used in fixup */
+               }
+
+             /* HP aCC generates operator names without the "operator" keyword, and
+                generates null strings as names for operators that are 
+                user-defined type conversions to basic types (e.g. operator int ()).
+                So try to reconstruct name as best as possible. */
+
+             method_name = (char *) (VT (objfile) + fn_fieldp->dfunc.name);
+             method_alias = (char *) (VT (objfile) + fn_fieldp->dfunc.alias);
+
+             if (!method_name ||       /* no name */
+                 !*method_name ||      /* or null name */
+                 cplus_mangle_opname (method_name, DMGL_ANSI))         /* or name is an operator like "<" */
+               {
+                 char *tmp_name = cplus_demangle (method_alias, DMGL_ANSI);
+                 char *op_string = strstr (tmp_name, "operator");
+                 method_name = xmalloc (strlen (op_string) + 1);       /* don't overwrite VT! */
+                 strcpy (method_name, op_string);
+               }
+
+             /* First check if a method of the same name has already been seen. */
+             fn_p = fn_list;
+             while (fn_p)
+               {
+                 if (STREQ (fn_p->field.name, method_name))
+                   break;
+                 fn_p = fn_p->next;
+               }
+
+             /* If no such method was found, allocate a new entry in the list */
+             if (!fn_p)
+               {
+                 /* Get space to record this member function */
+                 /* Note: alloca used; this will disappear on routine exit */
+                 fn_new = (struct next_fn_field *) alloca (sizeof (struct next_fn_field));
+                 fn_new->next = fn_list;
+                 fn_list = fn_new;
+
+                 /* Fill in the fields of the struct nextfield */
+
+                 /* Record the (unmangled) method name */
+                 fn_list->field.name = method_name;
+                 /* Initial space for overloaded methods */
+                 /* Note: xmalloc is used; this will persist after this routine exits */
+                 fn_list->field.fn_fields = (struct fn_field *) xmalloc (5 * (sizeof (struct fn_field)));
+                 fn_list->field.length = 1;    /* Init # of overloaded instances */
+                 fn_list->num_fn_fields = 5;   /* # of entries for which space allocated */
+                 fn_p = fn_list;
+                 ix = 0;       /* array index for fn_field */
+                 /* Bump the total count of the distinctly named methods */
+                 n_fn_fields++;
+               }
+             else
+               /* Another overloaded instance of an already seen method name */
+               {
+                 if (++(fn_p->field.length) > fn_p->num_fn_fields)
+                   {
+                     /* Increase space allocated for overloaded instances */
+                     fn_p->field.fn_fields
+                       = (struct fn_field *) xrealloc (fn_p->field.fn_fields,
+                     (fn_p->num_fn_fields + 5) * sizeof (struct fn_field));
+                     fn_p->num_fn_fields += 5;
+                   }
+                 ix = fn_p->field.length - 1;  /* array index for fn_field */
+               }
+
+             /* "physname" is intended to be the name of this overloaded instance. */
+             if ((fn_fieldp->dfunc.language == HP_LANGUAGE_CPLUSPLUS) &&
+                 method_alias &&
+                 *method_alias)        /* not a null string */
+               fn_p->field.fn_fields[ix].physname = method_alias;
+             else
+               fn_p->field.fn_fields[ix].physname = method_name;
+             /* What's expected here is the function type */
+             /* But mark it as NULL if the method was incompletely processed
+                We'll fix this up later when the method is fully processed */
+             if (TYPE_INCOMPLETE (memtype))
+               fn_p->field.fn_fields[ix].type = NULL;
+             else
+               fn_p->field.fn_fields[ix].type = memtype;
+
+             /* For virtual functions, fill in the voffset field with the
+              * virtual table offset. (This is just copied over from the
+              * SOM record; not sure if it is what GDB expects here...).
+              * But if the function is a static method, set it to 1.
+              * 
+              * Note that we have to add 1 because 1 indicates a static
+              * method, and 0 indicates a non-static, non-virtual method */
+
+             if (static_member)
+               fn_p->field.fn_fields[ix].voffset = VOFFSET_STATIC;
+             else
+               fn_p->field.fn_fields[ix].voffset = vtbl_offset ? vtbl_offset + 1 : 0;
+
+             /* Also fill in the fcontext field with the current
+              * class. (The latter isn't quite right: should be the baseclass
+              * that defines the virtual function... Note we do have
+              * a variable "baseclass" that we could stuff into the fcontext
+              * field, but "baseclass" isn't necessarily right either,
+              * since the virtual function could have been defined more
+              * than one level up).
+              */
+
+             if (vtbl_offset != 0)
+               fn_p->field.fn_fields[ix].fcontext = type;
+             else
+               fn_p->field.fn_fields[ix].fcontext = NULL;
+
+             /* Other random fields pertaining to this method */
+             fn_p->field.fn_fields[ix].is_const = const_member;
+             fn_p->field.fn_fields[ix].is_volatile = volatile_member;  /* ?? */
+             switch (fieldp->dgenfield.visibility)
+               {
+               case 1:
+                 fn_p->field.fn_fields[ix].is_protected = 1;
+                 fn_p->field.fn_fields[ix].is_private = 0;
+                 break;
+               case 2:
+                 fn_p->field.fn_fields[ix].is_protected = 0;
+                 fn_p->field.fn_fields[ix].is_private = 1;
+                 break;
+               default:        /* public */
+                 fn_p->field.fn_fields[ix].is_protected = 0;
+                 fn_p->field.fn_fields[ix].is_private = 0;
+               }
+             fn_p->field.fn_fields[ix].is_stub = 0;
+
+             /* HP aCC emits both MEMFUNC and FUNCTION entries for a method;
+                if the class points to the FUNCTION, there is usually separate
+                code for the method; but if we have a MEMFUNC, the method has
+                been inlined (and there is usually no FUNCTION entry)
+                FIXME Not sure if this test is accurate. pai/1997-08-22 */
+             if ((fn_fieldp->dblock.kind == DNTT_TYPE_MEMFUNC) ||
+                 (fn_fieldp->dblock.kind == DNTT_TYPE_DOC_MEMFUNC))
+               fn_p->field.fn_fields[ix].is_inlined = 1;
+             else
+               fn_p->field.fn_fields[ix].is_inlined = 0;
+
+             fn_p->field.fn_fields[ix].dummy = 0;
+
+             /* Bump the total count of the member functions */
+             n_fn_fields_total++;
+
+           }
+         else if (fn_fieldp->dblock.kind == DNTT_TYPE_SVAR)
+           {
+             /* This case is for static data members of classes */
+
+             /* pai:: FIXME -- check that "staticmem" bit is set */
+
+             /* Get space to record this static member */
+             new = (struct nextfield *) alloca (sizeof (struct nextfield));
+             new->next = list;
+             list = new;
+
+             list->field.name = VT (objfile) + fn_fieldp->dsvar.name;
+             SET_FIELD_PHYSNAME (list->field, 0);      /* initialize to empty */
+             memtype = hpread_type_lookup (fn_fieldp->dsvar.type, objfile);
+
+             FIELD_TYPE (list->field) = memtype;
+             list->attributes = 0;
+             switch (fieldp->dgenfield.visibility)
+               {
+               case 1:
+                 B_SET (&(list->attributes), ATTR_PROTECT);
+                 break;
+               case 2:
+                 B_SET (&(list->attributes), ATTR_PRIVATE);
+                 break;
+               }
+             nfields++;
+           }
+
+         else if (fn_fieldp->dblock.kind == DNTT_TYPE_FIELD)
+           {
+             /* FIELDs follow GENFIELDs for fields of anonymous unions.
+                Code below is replicated from the case for FIELDs further
+                below, except that fieldp is replaced by fn_fieldp */
+             if (!fn_fieldp->dfield.a_union)
+               warning ("Debug info inconsistent: FIELD of anonymous union doesn't have a_union bit set");
+             /* Get space to record the next field/data-member. */
+             new = (struct nextfield *) alloca (sizeof (struct nextfield));
+             new->next = list;
+             list = new;
+
+             list->field.name = VT (objfile) + fn_fieldp->dfield.name;
+             FIELD_BITPOS (list->field) = fn_fieldp->dfield.bitoffset;
+             if (fn_fieldp->dfield.bitlength % 8)
+               list->field.bitsize = fn_fieldp->dfield.bitlength;
+             else
+               list->field.bitsize = 0;
+
+             memtype = hpread_type_lookup (fn_fieldp->dfield.type, objfile);
+             list->field.type = memtype;
+             list->attributes = 0;
+             switch (fn_fieldp->dfield.visibility)
+               {
+               case 1:
+                 B_SET (&(list->attributes), ATTR_PROTECT);
+                 break;
+               case 2:
+                 B_SET (&(list->attributes), ATTR_PRIVATE);
+                 break;
+               }
+             nfields++;
+           }
+         else if (fn_fieldp->dblock.kind == DNTT_TYPE_SVAR)
+           {
+             /* Field of anonymous union; union is not inside a class */
+             if (!fn_fieldp->dsvar.a_union)
+               warning ("Debug info inconsistent: SVAR field in anonymous union doesn't have a_union bit set");
+             /* Get space to record the next field/data-member. */
+             new = (struct nextfield *) alloca (sizeof (struct nextfield));
+             new->next = list;
+             list = new;
+
+             list->field.name = VT (objfile) + fn_fieldp->dsvar.name;
+             FIELD_BITPOS (list->field) = 0;   /* FIXME is this always true? */
+             FIELD_BITSIZE (list->field) = 0;  /* use length from type */
+             memtype = hpread_type_lookup (fn_fieldp->dsvar.type, objfile);
+             list->field.type = memtype;
+             list->attributes = 0;
+             /* No info to set visibility -- always public */
+             nfields++;
+           }
+         else if (fn_fieldp->dblock.kind == DNTT_TYPE_DVAR)
+           {
+             /* Field of anonymous union; union is not inside a class */
+             if (!fn_fieldp->ddvar.a_union)
+               warning ("Debug info inconsistent: DVAR field in anonymous union doesn't have a_union bit set");
+             /* Get space to record the next field/data-member. */
+             new = (struct nextfield *) alloca (sizeof (struct nextfield));
+             new->next = list;
+             list = new;
+
+             list->field.name = VT (objfile) + fn_fieldp->ddvar.name;
+             FIELD_BITPOS (list->field) = 0;   /* FIXME is this always true? */
+             FIELD_BITSIZE (list->field) = 0;  /* use length from type */
+             memtype = hpread_type_lookup (fn_fieldp->ddvar.type, objfile);
+             list->field.type = memtype;
+             list->attributes = 0;
+             /* No info to set visibility -- always public */
+             nfields++;
+           }
+         else
+           {                   /* Not a method, nor a static data member, nor an anon union field */
+
+             /* This case is for miscellaneous type entries (local enums,
+                local function templates, etc.) that can be present
+                inside a class. */
+
+             /* Enums -- will be handled by other code that takes care
+                of DNTT_TYPE_ENUM; here we see only DNTT_TYPE_MEMENUM so
+                it's not clear we could have handled them here at all. */
+             /* FUNC_TEMPLATE: is handled by other code (?). */
+             /* MEMACCESS: modified access for inherited member. Not
+                sure what to do with this, ignoriing it at present. */
+
+             /* What other entries can appear following a GENFIELD which
+                we do not handle above?  (MODIFIER, VFUNC handled above.) */
+
+             if ((fn_fieldp->dblock.kind != DNTT_TYPE_MEMACCESS) &&
+                 (fn_fieldp->dblock.kind != DNTT_TYPE_MEMENUM) &&
+                 (fn_fieldp->dblock.kind != DNTT_TYPE_FUNC_TEMPLATE))
+               warning ("Internal error: Unexpected debug record kind %d found following DNTT_GENFIELD",
+                        fn_fieldp->dblock.kind);
+           }
+         /* walk to the next FIELD or GENFIELD */
+         field = fieldp->dgenfield.nextfield;
+
+       }
+      else if (fieldp->dblock.kind == DNTT_TYPE_FIELD)
+       {
+
+         /* Ordinary structure/union/class field */
+         struct type *anon_union_type;
+
+         /* Get space to record the next field/data-member. */
+         new = (struct nextfield *) alloca (sizeof (struct nextfield));
+         new->next = list;
+         list = new;
+
+         list->field.name = VT (objfile) + fieldp->dfield.name;
+
+
+         /* A FIELD by itself (without a GENFIELD) can also be a static member */
+         if (fieldp->dfield.staticmem)
+           {
+             FIELD_BITPOS (list->field) = -1;
+             FIELD_BITSIZE (list->field) = 0;
+           }
+         else
+           /* Non-static data member */
+           {
+             FIELD_BITPOS (list->field) = fieldp->dfield.bitoffset;
+             if (fieldp->dfield.bitlength % 8)
+               FIELD_BITSIZE (list->field) = fieldp->dfield.bitlength;
+             else
+               FIELD_BITSIZE (list->field) = 0;
+           }
+
+         memtype = hpread_type_lookup (fieldp->dfield.type, objfile);
+         FIELD_TYPE (list->field) = memtype;
+         list->attributes = 0;
+         switch (fieldp->dfield.visibility)
+           {
+           case 1:
+             B_SET (&(list->attributes), ATTR_PROTECT);
+             break;
+           case 2:
+             B_SET (&(list->attributes), ATTR_PRIVATE);
+             break;
+           }
+         nfields++;
+
+
+         /* Note 1: First, we have to check if the current field is an anonymous
+            union. If it is, then *its* fields are threaded along in the
+            nextfield chain. :-( This was supposed to help debuggers, but is
+            really just a nuisance since we deal with anonymous unions anyway by
+            checking that the name is null.  So anyway, we skip over the fields
+            of the anonymous union. pai/1997-08-22 */
+         /* Note 2: In addition, the bitoffsets for the fields of the anon union
+            are relative to the enclosing struct, *NOT* relative to the anon
+            union!  This is an even bigger nuisance -- we have to go in and munge
+            the anon union's type information appropriately. pai/1997-08-22 */
+
+         /* Both tasks noted above are done by a separate function.  This takes us
+            to the next FIELD or GENFIELD, skipping anon unions, and recursively
+            processing intermediate types. */
+         field = hpread_get_next_skip_over_anon_unions (1, field, &fieldp, objfile);
+
+       }
+      else
+       {
+         /* neither field nor genfield ?? is this possible?? */
+         /* pai:: FIXME walk to the next -- how? */
+         warning ("Internal error: unexpected DNTT kind %d encountered as field of struct",
+                  fieldp->dblock.kind);
+         warning ("Skipping remaining fields of struct");
+         break;                /* get out of loop of fields */
+       }
+    }
+
+  /* If it's a template, read in the instantiation list */
+  if (dn_bufp->dblock.kind == DNTT_TYPE_TEMPLATE)
+    {
+      ninstantiations = 0;
+      field = dn_bufp->dtemplate.expansions;
+      while (field.word && field.word != DNTTNIL)
+       {
+         fieldp = hpread_get_lntt (field.dnttp.index, objfile);
+
+         /* The expansions or nextexp should point to a tagdef */
+         if (fieldp->dblock.kind != DNTT_TYPE_TAGDEF)
+           break;
+
+         i_new = (struct next_instantiation *) alloca (sizeof (struct next_instantiation));
+         i_new->next = i_list;
+         i_list = i_new;
+         i_list->t = hpread_type_lookup (field, objfile);
+         ninstantiations++;
+
+         /* And the "type" field of that should point to a class */
+         field = fieldp->dtag.type;
+         fieldp = hpread_get_lntt (field.dnttp.index, objfile);
+         if (fieldp->dblock.kind != DNTT_TYPE_CLASS)
+           break;
+
+         /* Get the next expansion */
+         field = fieldp->dclass.nextexp;
+       }
+    }
+  TYPE_NINSTANTIATIONS (type) = ninstantiations;
+  if (ninstantiations > 0)
+    TYPE_INSTANTIATIONS (type) = (struct type **)
+      obstack_alloc (&objfile->type_obstack, sizeof (struct type *) * ninstantiations);
+  for (n = ninstantiations; i_list; i_list = i_list->next)
+    {
+      n -= 1;
+      TYPE_INSTANTIATION (type, n) = i_list->t;
+    }
+
+
+  /* Copy the field-list to GDB's symbol table */
+  TYPE_NFIELDS (type) = nfields;
+  TYPE_N_BASECLASSES (type) = n_base_classes;
+  TYPE_FIELDS (type) = (struct field *)
+    obstack_alloc (&objfile->type_obstack, sizeof (struct field) * nfields);
+  /* Copy the saved-up fields into the field vector.  */
+  for (n = nfields, tmp_list = list; tmp_list; tmp_list = tmp_list->next)
+    {
+      n -= 1;
+      TYPE_FIELD (type, n) = tmp_list->field;
+    }
+
+  /* Copy the "function-field-list" (i.e., the list of member
+   * functions in the class) to GDB's symbol table 
+   */
+  TYPE_NFN_FIELDS (type) = n_fn_fields;
+  TYPE_NFN_FIELDS_TOTAL (type) = n_fn_fields_total;
+  TYPE_FN_FIELDLISTS (type) = (struct fn_fieldlist *)
+    obstack_alloc (&objfile->type_obstack, sizeof (struct fn_fieldlist) * n_fn_fields);
+  for (n = n_fn_fields; fn_list; fn_list = fn_list->next)
+    {
+      n -= 1;
+      TYPE_FN_FIELDLIST (type, n) = fn_list->field;
+    }
+
+  /* pai:: FIXME -- perhaps each bitvector should be created individually */
+  for (n = nfields, tmp_list = list; tmp_list; tmp_list = tmp_list->next)
+    {
+      n -= 1;
+      if (tmp_list->attributes)
+       {
+         need_bitvectors = 1;
+         break;
+       }
+    }
+
+  if (need_bitvectors)
+    {
+      /* pai:: this step probably redundant */
+      ALLOCATE_CPLUS_STRUCT_TYPE (type);
+
+      TYPE_FIELD_VIRTUAL_BITS (type) =
+       (B_TYPE *) TYPE_ALLOC (type, B_BYTES (nfields));
+      B_CLRALL (TYPE_FIELD_VIRTUAL_BITS (type), nfields);
+
+      TYPE_FIELD_PRIVATE_BITS (type) =
+       (B_TYPE *) TYPE_ALLOC (type, B_BYTES (nfields));
+      B_CLRALL (TYPE_FIELD_PRIVATE_BITS (type), nfields);
+
+      TYPE_FIELD_PROTECTED_BITS (type) =
+       (B_TYPE *) TYPE_ALLOC (type, B_BYTES (nfields));
+      B_CLRALL (TYPE_FIELD_PROTECTED_BITS (type), nfields);
+
+      /* this field vector isn't actually used with HP aCC */
+      TYPE_FIELD_IGNORE_BITS (type) =
+       (B_TYPE *) TYPE_ALLOC (type, B_BYTES (nfields));
+      B_CLRALL (TYPE_FIELD_IGNORE_BITS (type), nfields);
+
+      while (nfields-- > 0)
+       {
+         if (B_TST (&(list->attributes), ATTR_VIRTUAL))
+           SET_TYPE_FIELD_VIRTUAL (type, nfields);
+         if (B_TST (&(list->attributes), ATTR_PRIVATE))
+           SET_TYPE_FIELD_PRIVATE (type, nfields);
+         if (B_TST (&(list->attributes), ATTR_PROTECT))
+           SET_TYPE_FIELD_PROTECTED (type, nfields);
+
+         list = list->next;
+       }
+    }
+  else
+    {
+      TYPE_FIELD_VIRTUAL_BITS (type) = NULL;
+      TYPE_FIELD_PROTECTED_BITS (type) = NULL;
+      TYPE_FIELD_PRIVATE_BITS (type) = NULL;
+    }
+
+  if (has_vtable (type))
+    {
+      /* Allocate space for class runtime information */
+      TYPE_RUNTIME_PTR (type) = (struct runtime_info *) xmalloc (sizeof (struct runtime_info));
+      /* Set flag for vtable */
+      TYPE_VTABLE (type) = 1;
+      /* The first non-virtual base class with a vtable. */
+      TYPE_PRIMARY_BASE (type) = primary_base_class (type);
+      /* The virtual base list. */
+      TYPE_VIRTUAL_BASE_LIST (type) = virtual_base_list (type);
+    }
+  else
+    TYPE_RUNTIME_PTR (type) = NULL;
+
+  /* If this is a local type (C++ - declared inside a function), record file name & line # */
+  if (hpread_get_scope_depth (dn_bufp, objfile, 1 /* no need for real depth */ ))
+    {
+      TYPE_LOCALTYPE_PTR (type) = (struct local_type_info *) xmalloc (sizeof (struct local_type_info));
+      TYPE_LOCALTYPE_FILE (type) = (char *) xmalloc (strlen (current_subfile->name) + 1);
+      strcpy (TYPE_LOCALTYPE_FILE (type), current_subfile->name);
+      if (current_subfile->line_vector && (current_subfile->line_vector->nitems > 0))
+       TYPE_LOCALTYPE_LINE (type) = current_subfile->line_vector->item[current_subfile->line_vector->nitems - 1].line;
+      else
+       TYPE_LOCALTYPE_LINE (type) = 0;
+    }
+  else
+    TYPE_LOCALTYPE_PTR (type) = NULL;
+
+  /* Clear the global saying what template we are in the middle of processing */
+  current_template = NULL;
+
+  return type;
+}
+
+/* Adjust the physnames for each static member of a struct
+   or class type to be something like "A::x"; then various
+   other pieces of code that do a lookup_symbol on the phyname
+   work correctly.
+   TYPE is a pointer to the struct/class type
+   NAME is a char * (string) which is the class/struct name
+   Void return */
+
+static void
+fix_static_member_physnames (struct type *type, char *class_name,
+                            struct objfile *objfile)
+{
+  int i;
+
+  /* We fix the member names only for classes or structs */
+  if (TYPE_CODE (type) != TYPE_CODE_STRUCT)
+    return;
+
+  for (i = 0; i < TYPE_NFIELDS (type); i++)
+    if (TYPE_FIELD_STATIC (type, i))
+      {
+       if (TYPE_FIELD_STATIC_PHYSNAME (type, i))
+         return;               /* physnames are already set */
+
+       SET_FIELD_PHYSNAME (TYPE_FIELDS (type)[i],
+                           obstack_alloc (&objfile->type_obstack,
+            strlen (class_name) + strlen (TYPE_FIELD_NAME (type, i)) + 3));
+       strcpy (TYPE_FIELD_STATIC_PHYSNAME (type, i), class_name);
+       strcat (TYPE_FIELD_STATIC_PHYSNAME (type, i), "::");
+       strcat (TYPE_FIELD_STATIC_PHYSNAME (type, i), TYPE_FIELD_NAME (type, i));
+      }
+}
+
+/* Fix-up the type structure for a CLASS so that the type entry
+ * for a method (previously marked with a null type in hpread_read_struct_type()
+ * is set correctly to METHOD.
+ * OBJFILE is as for other such functions. 
+ * Void return. */
+
+static void
+fixup_class_method_type (struct type *class, struct type *method,
+                        struct objfile *objfile)
+{
+  int i, j, k;
+
+  if (!class || !method || !objfile)
+    return;
+
+  /* Only for types that have methods */
+  if ((TYPE_CODE (class) != TYPE_CODE_CLASS) &&
+      (TYPE_CODE (class) != TYPE_CODE_UNION))
+    return;
+
+  /* Loop over all methods and find the one marked with a NULL type */
+  for (i = 0; i < TYPE_NFN_FIELDS (class); i++)
+    for (j = 0; j < TYPE_FN_FIELDLIST_LENGTH (class, i); j++)
+      if (TYPE_FN_FIELD_TYPE (TYPE_FN_FIELDLIST1 (class, i), j) == NULL)
+       {
+         /* Set the method type */
+         TYPE_FN_FIELD_TYPE (TYPE_FN_FIELDLIST1 (class, i), j) = method;
+
+         /* Break out of both loops -- only one method to fix up in a class */
+         goto finish;
+       }
+
+finish:
+  TYPE_FLAGS (class) &= ~TYPE_FLAG_INCOMPLETE;
+}
+
+
+/* If we're in the middle of processing a template, get a pointer
+ * to the Nth template argument.
+ * An example may make this clearer:
+ *   template <class T1, class T2> class q2 {
+ *     public:
+ *     T1 a;
+ *     T2 b;
+ *   };
+ * The type for "a" will be "first template arg" and
+ * the type for "b" will be "second template arg".
+ * We need to look these up in order to fill in "a" and "b"'s type.
+ * This is called from hpread_type_lookup().
+ */
+static struct type *
+hpread_get_nth_template_arg (struct objfile *objfile, int n)
+{
+  if (current_template != NULL)
+    return TYPE_TEMPLATE_ARG (current_template, n).type;
+  else
+    return lookup_fundamental_type (objfile, FT_TEMPLATE_ARG);
+}
+
+/* Read in and internalize a TEMPL_ARG (template arg) symbol.  */
+
+static struct type *
+hpread_read_templ_arg_type (dnttpointer hp_type, union dnttentry *dn_bufp,
+                           struct objfile *objfile, char *name)
+{
+  struct type *type;
+
+  /* See if it's something we've already deal with.  */
+  type = hpread_alloc_type (hp_type, objfile);
+  if (TYPE_CODE (type) == TYPE_CODE_TEMPLATE_ARG)
+    return type;
+
+  /* Nope.  Fill in the appropriate fields.  */
+  TYPE_CODE (type) = TYPE_CODE_TEMPLATE_ARG;
+  TYPE_LENGTH (type) = 0;
+  TYPE_NFIELDS (type) = 0;
+  TYPE_NAME (type) = name;
+  return type;
+}
+
+/* Read in and internalize a set debug symbol.  */
+
+static struct type *
+hpread_read_set_type (dnttpointer hp_type, union dnttentry *dn_bufp,
+                     struct objfile *objfile)
+{
+  struct type *type;
+
+  /* See if it's something we've already deal with.  */
+  type = hpread_alloc_type (hp_type, objfile);
+  if (TYPE_CODE (type) == TYPE_CODE_SET)
+    return type;
+
+  /* Nope.  Fill in the appropriate fields.  */
+  TYPE_CODE (type) = TYPE_CODE_SET;
+  TYPE_LENGTH (type) = dn_bufp->dset.bitlength / 8;
+  TYPE_NFIELDS (type) = 0;
+  TYPE_TARGET_TYPE (type) = hpread_type_lookup (dn_bufp->dset.subtype,
+                                               objfile);
+  return type;
+}
+
+/* Read in and internalize an array debug symbol.  */
+
+static struct type *
+hpread_read_array_type (dnttpointer hp_type, union dnttentry *dn_bufp,
+                       struct objfile *objfile)
+{
+  struct type *type;
+
+  /* Allocate an array type symbol.
+   * Why no check for already-read here, like in the other
+   * hpread_read_xxx_type routines?  Because it kept us 
+   * from properly determining the size of the array!  
+   */
+  type = hpread_alloc_type (hp_type, objfile);
+
+  TYPE_CODE (type) = TYPE_CODE_ARRAY;
+
+  /* Although the hp-symtab.h does not *require* this to be the case,
+   * GDB is assuming that "arrayisbytes" and "elemisbytes" be consistent.
+   * I.e., express both array-length and element-length in bits,
+   * or express both array-length and element-length in bytes.
+   */
+  if (!((dn_bufp->darray.arrayisbytes && dn_bufp->darray.elemisbytes) ||
+       (!dn_bufp->darray.arrayisbytes && !dn_bufp->darray.elemisbytes)))
+    {
+      warning ("error in hpread_array_type.\n");
+      return NULL;
+    }
+  else if (dn_bufp->darray.arraylength == 0x7fffffff)
+    {
+      /* The HP debug format represents char foo[]; as an array with
+       * length 0x7fffffff.  Internally GDB wants to represent this
+       *  as an array of length zero.  
+       */
+      TYPE_LENGTH (type) = 0;
+    }
+  else if (dn_bufp->darray.arrayisbytes)
+    TYPE_LENGTH (type) = dn_bufp->darray.arraylength;
+  else                         /* arraylength is in bits */
+    TYPE_LENGTH (type) = dn_bufp->darray.arraylength / 8;
+
+  TYPE_TARGET_TYPE (type) = hpread_type_lookup (dn_bufp->darray.elemtype,
+                                               objfile);
+
+  /* The one "field" is used to store the subscript type */
+  /* Since C and C++ multi-dimensional arrays are simply represented
+   * as: array of array of ..., we only need one subscript-type
+   * per array. This subscript type is typically a subrange of integer.
+   * If this gets extended to support languages like Pascal, then
+   * we need to fix this to represent multi-dimensional arrays properly.
+   */
+  TYPE_NFIELDS (type) = 1;
+  TYPE_FIELDS (type) = (struct field *)
+    obstack_alloc (&objfile->type_obstack, sizeof (struct field));
+  TYPE_FIELD_TYPE (type, 0) = hpread_type_lookup (dn_bufp->darray.indextype,
+                                                 objfile);
+  return type;
+}
+
+/* Read in and internalize a subrange debug symbol.  */
+static struct type *
+hpread_read_subrange_type (dnttpointer hp_type, union dnttentry *dn_bufp,
+                          struct objfile *objfile)
+{
+  struct type *type;
+
+  /* Is it something we've already dealt with.  */
+  type = hpread_alloc_type (hp_type, objfile);
+  if (TYPE_CODE (type) == TYPE_CODE_RANGE)
+    return type;
+
+  /* Nope, internalize it.  */
+  TYPE_CODE (type) = TYPE_CODE_RANGE;
+  TYPE_LENGTH (type) = dn_bufp->dsubr.bitlength / 8;
+  TYPE_NFIELDS (type) = 2;
+  TYPE_FIELDS (type)
+    = (struct field *) obstack_alloc (&objfile->type_obstack,
+                                     2 * sizeof (struct field));
+
+  if (dn_bufp->dsubr.dyn_low)
+    TYPE_FIELD_BITPOS (type, 0) = 0;
+  else
+    TYPE_FIELD_BITPOS (type, 0) = dn_bufp->dsubr.lowbound;
+
+  if (dn_bufp->dsubr.dyn_high)
+    TYPE_FIELD_BITPOS (type, 1) = -1;
+  else
+    TYPE_FIELD_BITPOS (type, 1) = dn_bufp->dsubr.highbound;
+  TYPE_TARGET_TYPE (type) = hpread_type_lookup (dn_bufp->dsubr.subtype,
+                                               objfile);
+  return type;
+}
+
+/* struct type * hpread_type_lookup(hp_type, objfile)
+ *   Arguments:
+ *     hp_type: A pointer into the DNTT specifying what type we
+ *              are about to "look up"., or else [for fundamental types
+ *              like int, float, ...] an "immediate" structure describing
+ *              the type.
+ *     objfile: ?
+ *   Return value: A pointer to a "struct type" (representation of a
+ *                 type in GDB's internal symbol table - see gdbtypes.h)
+ *   Routine description:
+ *     There are a variety of places when scanning the DNTT when we
+ *     need to interpret a "type" field. The simplest and most basic 
+ *     example is when we're processing the symbol table record
+ *     for a data symbol (a SVAR or DVAR record). That has
+ *     a "type" field specifying the type of the data symbol. That
+ *     "type" field is either an "immediate" type specification (for the
+ *     fundamental types) or a DNTT pointer (for more complicated types). 
+ *     For the more complicated types, we may or may not have already
+ *     processed the pointed-to type. (Multiple data symbols can of course
+ *     share the same type).
+ *     The job of hpread_type_lookup() is to process this "type" field.
+ *     Most of the real work is done in subroutines. Here we interpret
+ *     the immediate flag. If not immediate, chase the DNTT pointer to
+ *     find our way to the SOM record describing the type, switch on
+ *     the SOM kind, and then call an appropriate subroutine depending
+ *     on what kind of type we are constructing. (e.g., an array type,
+ *     a struct/class type, etc).
+ */
+static struct type *
+hpread_type_lookup (dnttpointer hp_type, struct objfile *objfile)
+{
+  union dnttentry *dn_bufp;
+  struct type *tmp_type;
+
+  /* First see if it's a simple builtin type.  */
+  if (hp_type.dntti.immediate)
+    {
+      /* If this is a template argument, the argument number is
+       * encoded in the bitlength. All other cases, just return
+       * GDB's representation of this fundamental type.
+       */
+      if (hp_type.dntti.type == HP_TYPE_TEMPLATE_ARG)
+       return hpread_get_nth_template_arg (objfile, hp_type.dntti.bitlength);
+      else
+       return lookup_fundamental_type (objfile,
+                                       hpread_type_translate (hp_type));
+    }
+
+  /* Not a builtin type.  We'll have to read it in.  */
+  if (hp_type.dnttp.index < LNTT_SYMCOUNT (objfile))
+    dn_bufp = hpread_get_lntt (hp_type.dnttp.index, objfile);
+  else
+    /* This is a fancy way of returning NULL */
+    return lookup_fundamental_type (objfile, FT_VOID);
+
+  switch (dn_bufp->dblock.kind)
+    {
+    case DNTT_TYPE_SRCFILE:
+    case DNTT_TYPE_MODULE:
+    case DNTT_TYPE_ENTRY:
+    case DNTT_TYPE_BEGIN:
+    case DNTT_TYPE_END:
+    case DNTT_TYPE_IMPORT:
+    case DNTT_TYPE_LABEL:
+    case DNTT_TYPE_FPARAM:
+    case DNTT_TYPE_SVAR:
+    case DNTT_TYPE_DVAR:
+    case DNTT_TYPE_CONST:
+    case DNTT_TYPE_MEMENUM:
+    case DNTT_TYPE_VARIANT:
+    case DNTT_TYPE_FILE:
+    case DNTT_TYPE_WITH:
+    case DNTT_TYPE_COMMON:
+    case DNTT_TYPE_COBSTRUCT:
+    case DNTT_TYPE_XREF:
+    case DNTT_TYPE_SA:
+    case DNTT_TYPE_MACRO:
+    case DNTT_TYPE_BLOCKDATA:
+    case DNTT_TYPE_CLASS_SCOPE:
+    case DNTT_TYPE_MEMACCESS:
+    case DNTT_TYPE_INHERITANCE:
+    case DNTT_TYPE_OBJECT_ID:
+    case DNTT_TYPE_FRIEND_CLASS:
+    case DNTT_TYPE_FRIEND_FUNC:
+      /* These are not types - something went wrong.  */
+      /* This is a fancy way of returning NULL */
+      return lookup_fundamental_type (objfile, FT_VOID);
+
+    case DNTT_TYPE_FUNCTION:
+      /* We wind up here when dealing with class member functions 
+       * (called from hpread_read_struct_type(), i.e. when processing
+       * the class definition itself).
+       */
+      return hpread_read_function_type (hp_type, dn_bufp, objfile, 0);
+
+    case DNTT_TYPE_DOC_FUNCTION:
+      return hpread_read_doc_function_type (hp_type, dn_bufp, objfile, 0);
+
+    case DNTT_TYPE_TYPEDEF:
+      {
+       /* A typedef - chase it down by making a recursive call */
+       struct type *structtype = hpread_type_lookup (dn_bufp->dtype.type,
+                                                     objfile);
+
+       /* The following came from the base hpread.c that we inherited.
+        * It is WRONG so I have commented it out. - RT
+        *...
+
+        char *suffix;
+        suffix = VT (objfile) + dn_bufp->dtype.name;
+        TYPE_NAME (structtype) = suffix;
+
+        * ... further explanation ....
+        *
+        * What we have here is a typedef pointing to a typedef.
+        * E.g.,
+        * typedef int foo;
+        * typedef foo fum;
+        *
+        * What we desire to build is (these are pictures
+        * of "struct type"'s): 
+        *
+        *  +---------+     +----------+     +------------+
+        *  | typedef |     | typedef  |     | fund. type |
+        *  |     type| ->  |      type| ->  |            |
+        *  | "fum"   |     | "foo"    |     | "int"      |
+        *  +---------+     +----------+     +------------+
+        *
+        * What this commented-out code is doing is smashing the
+        * name of pointed-to-type to be the same as the pointed-from
+        * type. So we wind up with something like:
+        *
+        *  +---------+     +----------+     +------------+
+        *  | typedef |     | typedef  |     | fund. type |
+        *  |     type| ->  |      type| ->  |            |
+        *  | "fum"   |     | "fum"    |     | "fum"      |
+        *  +---------+     +----------+     +------------+
+        * 
+        */
+
+       return structtype;
+      }
+
+    case DNTT_TYPE_TAGDEF:
+      {
+       /* Just a little different from above.  We have to tack on
+        * an identifier of some kind (struct, union, enum, class, etc).  
+        */
+       struct type *structtype = hpread_type_lookup (dn_bufp->dtype.type,
+                                                     objfile);
+       char *prefix, *suffix;
+       suffix = VT (objfile) + dn_bufp->dtype.name;
+
+       /* Lookup the next type in the list.  It should be a structure,
+        * union, class, enum, or template type.  
+        * We will need to attach that to our name.  
+        */
+       if (dn_bufp->dtype.type.dnttp.index < LNTT_SYMCOUNT (objfile))
+         dn_bufp = hpread_get_lntt (dn_bufp->dtype.type.dnttp.index, objfile);
+       else
+         {
+           complain (&hpread_type_lookup_complaint);
+           return NULL;
+         }
+
+       if (dn_bufp->dblock.kind == DNTT_TYPE_STRUCT)
+         {
+           prefix = "struct ";
+         }
+       else if (dn_bufp->dblock.kind == DNTT_TYPE_UNION)
+         {
+           prefix = "union ";
+         }
+       else if (dn_bufp->dblock.kind == DNTT_TYPE_CLASS)
+         {
+           /* Further field for CLASS saying how it was really declared */
+           /* 0==class, 1==union, 2==struct */
+           if (dn_bufp->dclass.class_decl == 0)
+             prefix = "class ";
+           else if (dn_bufp->dclass.class_decl == 1)
+             prefix = "union ";
+           else if (dn_bufp->dclass.class_decl == 2)
+             prefix = "struct ";
+           else
+             prefix = "";
+         }
+       else if (dn_bufp->dblock.kind == DNTT_TYPE_ENUM)
+         {
+           prefix = "enum ";
+         }
+       else if (dn_bufp->dblock.kind == DNTT_TYPE_TEMPLATE)
+         {
+           prefix = "template ";
+         }
+       else
+         {
+           prefix = "";
+         }
+
+       /* Build the correct name.  */
+       TYPE_NAME (structtype)
+         = (char *) obstack_alloc (&objfile->type_obstack,
+                                   strlen (prefix) + strlen (suffix) + 1);
+       TYPE_NAME (structtype) = strcpy (TYPE_NAME (structtype), prefix);
+       TYPE_NAME (structtype) = strcat (TYPE_NAME (structtype), suffix);
+       TYPE_TAG_NAME (structtype) = suffix;
+
+       /* For classes/structs, we have to set the static member "physnames"
+          to point to strings like "Class::Member" */
+       if (TYPE_CODE (structtype) == TYPE_CODE_STRUCT)
+         fix_static_member_physnames (structtype, suffix, objfile);
+
+       return structtype;
+      }
+
+    case DNTT_TYPE_POINTER:
+      /* Pointer type - call a routine in gdbtypes.c that constructs
+       * the appropriate GDB type.
+       */
+      return make_pointer_type (
+                                hpread_type_lookup (dn_bufp->dptr.pointsto,
+                                                    objfile),
+                                NULL);
+
+    case DNTT_TYPE_REFERENCE:
+      /* C++ reference type - call a routine in gdbtypes.c that constructs
+       * the appropriate GDB type.
+       */
+      return make_reference_type (
+                          hpread_type_lookup (dn_bufp->dreference.pointsto,
+                                              objfile),
+                                  NULL);
+
+    case DNTT_TYPE_ENUM:
+      return hpread_read_enum_type (hp_type, dn_bufp, objfile);
+    case DNTT_TYPE_SET:
+      return hpread_read_set_type (hp_type, dn_bufp, objfile);
+    case DNTT_TYPE_SUBRANGE:
+      return hpread_read_subrange_type (hp_type, dn_bufp, objfile);
+    case DNTT_TYPE_ARRAY:
+      return hpread_read_array_type (hp_type, dn_bufp, objfile);
+    case DNTT_TYPE_STRUCT:
+    case DNTT_TYPE_UNION:
+      return hpread_read_struct_type (hp_type, dn_bufp, objfile);
+    case DNTT_TYPE_FIELD:
+      return hpread_type_lookup (dn_bufp->dfield.type, objfile);
+
+    case DNTT_TYPE_FUNCTYPE:
+      /* Here we want to read the function SOMs and return a 
+       * type for it. We get here, for instance, when processing
+       * pointer-to-function type.
+       */
+      return hpread_read_function_type (hp_type, dn_bufp, objfile, 0);
+
+    case DNTT_TYPE_PTRMEM:
+      /* Declares a C++ pointer-to-data-member type. 
+       * The "pointsto" field defines the class,
+       * while the "memtype" field defines the pointed-to-type.
+       */
+      {
+       struct type *ptrmemtype;
+       struct type *class_type;
+       struct type *memtype;
+       memtype = hpread_type_lookup (dn_bufp->dptrmem.memtype,
+                                     objfile),
+         class_type = hpread_type_lookup (dn_bufp->dptrmem.pointsto,
+                                          objfile),
+         ptrmemtype = alloc_type (objfile);
+       smash_to_member_type (ptrmemtype, class_type, memtype);
+       return make_pointer_type (ptrmemtype, NULL);
+      }
+      break;
+
+    case DNTT_TYPE_PTRMEMFUNC:
+      /* Defines a C++ pointer-to-function-member type. 
+       * The "pointsto" field defines the class,
+       * while the "memtype" field defines the pointed-to-type.
+       */
+      {
+       struct type *ptrmemtype;
+       struct type *class_type;
+       struct type *functype;
+       struct type *retvaltype;
+       int nargs;
+       int i;
+       class_type = hpread_type_lookup (dn_bufp->dptrmem.pointsto,
+                                        objfile);
+       functype = hpread_type_lookup (dn_bufp->dptrmem.memtype,
+                                      objfile);
+       retvaltype = TYPE_TARGET_TYPE (functype);
+       nargs = TYPE_NFIELDS (functype);
+       ptrmemtype = alloc_type (objfile);
+
+       smash_to_method_type (ptrmemtype, class_type, retvaltype,
+                             TYPE_FIELDS (functype),
+                             TYPE_NFIELDS (functype),
+                             0);
+       return make_pointer_type (ptrmemtype, NULL);
+      }
+      break;
+
+    case DNTT_TYPE_CLASS:
+      return hpread_read_struct_type (hp_type, dn_bufp, objfile);
+
+    case DNTT_TYPE_GENFIELD:
+      /* Chase pointer from GENFIELD to FIELD, and make recursive
+       * call on that.
+       */
+      return hpread_type_lookup (dn_bufp->dgenfield.field, objfile);
+
+    case DNTT_TYPE_VFUNC:
+      /* C++ virtual function.
+       * We get here in the course of processing a class type which
+       * contains virtual functions. Just go through another level
+       * of indirection to get to the pointed-to function SOM.
+       */
+      return hpread_type_lookup (dn_bufp->dvfunc.funcptr, objfile);
+
+    case DNTT_TYPE_MODIFIER:
+      /* Check the modifiers and then just make a recursive call on
+       * the "type" pointed to by the modifier DNTT.
+       * 
+       * pai:: FIXME -- do we ever want to handle "m_duplicate" and
+       * "m_void" modifiers?  Is static_flag really needed here?
+       * (m_static used for methods of classes, elsewhere).
+       */
+      tmp_type = make_cv_type (dn_bufp->dmodifier.m_const,
+                              dn_bufp->dmodifier.m_volatile,
+                     hpread_type_lookup (dn_bufp->dmodifier.type, objfile),
+                              0);
+      return tmp_type;
+
+
+    case DNTT_TYPE_MEMFUNC:
+      /* Member function. Treat like a function.
+       * I think we get here in the course of processing a 
+       * pointer-to-member-function type...
+       */
+      return hpread_read_function_type (hp_type, dn_bufp, objfile, 0);
+
+    case DNTT_TYPE_DOC_MEMFUNC:
+      return hpread_read_doc_function_type (hp_type, dn_bufp, objfile, 0);
+
+    case DNTT_TYPE_TEMPLATE:
+      /* Template - sort of the header for a template definition,
+       * which like a class, points to a member list and also points
+       * to a TEMPLATE_ARG list of type-arguments.
+       */
+      return hpread_read_struct_type (hp_type, dn_bufp, objfile);
+
+    case DNTT_TYPE_TEMPLATE_ARG:
+      {
+       char *name;
+       /* The TEMPLATE record points to an argument list of
+        * TEMPLATE_ARG records, each of which describes one
+        * of the type-arguments. 
+        */
+       name = VT (objfile) + dn_bufp->dtempl_arg.name;
+       return hpread_read_templ_arg_type (hp_type, dn_bufp, objfile, name);
+      }
+
+    case DNTT_TYPE_FUNC_TEMPLATE:
+      /* We wind up here when processing a TEMPLATE type, 
+       * if the template has member function(s).
+       * Treat it like a FUNCTION.
+       */
+      return hpread_read_function_type (hp_type, dn_bufp, objfile, 0);
+
+    case DNTT_TYPE_LINK:
+      /* The LINK record is used to link up templates with instantiations.
+       * There is no type associated with the LINK record per se.
+       */
+      return lookup_fundamental_type (objfile, FT_VOID);
+
+      /* Also not yet handled... */
+      /* case DNTT_TYPE_DYN_ARRAY_DESC: */
+      /* case DNTT_TYPE_DESC_SUBRANGE: */
+      /* case DNTT_TYPE_BEGIN_EXT: */
+      /* case DNTT_TYPE_INLN: */
+      /* case DNTT_TYPE_INLN_LIST: */
+      /* case DNTT_TYPE_ALIAS: */
+    default:
+      /* A fancy way of returning NULL */
+      return lookup_fundamental_type (objfile, FT_VOID);
+    }
+}
+
+static sltpointer
+hpread_record_lines (struct subfile *subfile, sltpointer s_idx,
+                    sltpointer e_idx, struct objfile *objfile,
+                    CORE_ADDR offset)
+{
+  union sltentry *sl_bufp;
+
+  while (s_idx <= e_idx)
+    {
+      sl_bufp = hpread_get_slt (s_idx, objfile);
+      /* Only record "normal" entries in the SLT.  */
+      if (sl_bufp->snorm.sltdesc == SLT_NORMAL
+         || sl_bufp->snorm.sltdesc == SLT_EXIT)
+       record_line (subfile, sl_bufp->snorm.line,
+                    sl_bufp->snorm.address + offset);
+      else if (sl_bufp->snorm.sltdesc == SLT_NORMAL_OFFSET)
+       record_line (subfile, sl_bufp->snormoff.line,
+                    sl_bufp->snormoff.address + offset);
+      s_idx++;
+    }
+  return e_idx;
+}
+
+/* Given a function "f" which is a member of a class, find
+ * the classname that it is a member of. Used to construct
+ * the name (e.g., "c::f") which GDB will put in the
+ * "demangled name" field of the function's symbol.
+ * Called from hpread_process_one_debug_symbol()
+ * If "f" is not a member function, return NULL.
+ */
+char *
+class_of (struct type *functype)
+{
+  struct type *first_param_type;
+  char *first_param_name;
+  struct type *pointed_to_type;
+  char *class_name;
+
+  /* Check that the function has a first argument "this",
+   * and that "this" is a pointer to a class. If not,
+   * functype is not a member function, so return NULL.
+   */
+  if (TYPE_NFIELDS (functype) == 0)
+    return NULL;
+  first_param_name = TYPE_FIELD_NAME (functype, 0);
+  if (first_param_name == NULL)
+    return NULL;               /* paranoia */
+  if (strcmp (first_param_name, "this"))
+    return NULL;
+  first_param_type = TYPE_FIELD_TYPE (functype, 0);
+  if (first_param_type == NULL)
+    return NULL;               /* paranoia */
+  if (TYPE_CODE (first_param_type) != TYPE_CODE_PTR)
+    return NULL;
+
+  /* Get the thing that "this" points to, check that
+   * it's a class, and get its class name.
+   */
+  pointed_to_type = TYPE_TARGET_TYPE (first_param_type);
+  if (pointed_to_type == NULL)
+    return NULL;               /* paranoia */
+  if (TYPE_CODE (pointed_to_type) != TYPE_CODE_CLASS)
+    return NULL;
+  class_name = TYPE_NAME (pointed_to_type);
+  if (class_name == NULL)
+    return NULL;               /* paranoia */
+
+  /* The class name may be of the form "class c", in which case
+   * we want to strip off the leading "class ".
+   */
+  if (strncmp (class_name, "class ", 6) == 0)
+    class_name += 6;
+
+  return class_name;
+}
+
+/* Internalize one native debug symbol. 
+ * Called in a loop from hpread_expand_symtab(). 
+ * Arguments:
+ *   dn_bufp: 
+ *   name: 
+ *   section_offsets:
+ *   objfile:
+ *   text_offset: 
+ *   text_size: 
+ *   filename: 
+ *   index:             Index of this symbol
+ *   at_module_boundary_p Pointer to boolean flag to control caller's loop.
+ */
+
+static void
+hpread_process_one_debug_symbol (union dnttentry *dn_bufp, char *name,
+                                struct section_offsets *section_offsets,
+                                struct objfile *objfile, CORE_ADDR text_offset,
+                                int text_size, char *filename, int index,
+                                int *at_module_boundary_p)
+{
+  unsigned long desc;
+  int type;
+  CORE_ADDR valu;
+  int offset = ANOFFSET (section_offsets, SECT_OFF_TEXT (objfile));
+  int data_offset = ANOFFSET (section_offsets, SECT_OFF_DATA (objfile));
+  union dnttentry *dn_temp;
+  dnttpointer hp_type;
+  struct symbol *sym;
+  struct context_stack *new;
+  char *class_scope_name;
+
+  /* Allocate one GDB debug symbol and fill in some default values. */
+  sym = (struct symbol *) obstack_alloc (&objfile->symbol_obstack,
+                                        sizeof (struct symbol));
+  memset (sym, 0, sizeof (struct symbol));
+  SYMBOL_NAME (sym) = obsavestring (name, strlen (name), &objfile->symbol_obstack);
+  SYMBOL_LANGUAGE (sym) = language_auto;
+  SYMBOL_NAMESPACE (sym) = VAR_NAMESPACE;
+  SYMBOL_LINE (sym) = 0;
+  SYMBOL_VALUE (sym) = 0;
+  SYMBOL_CLASS (sym) = LOC_TYPEDEF;
+
+  /* Just a trick in case the SOM debug symbol is a type definition.
+   * There are routines that are set up to build a GDB type symbol, given
+   * a SOM dnttpointer. So we set up a dummy SOM dnttpointer "hp_type".
+   * This allows us to call those same routines.
+   */
+  hp_type.dnttp.extension = 1;
+  hp_type.dnttp.immediate = 0;
+  hp_type.dnttp.global = 0;
+  hp_type.dnttp.index = index;
+
+  /* This "type" is the type of SOM record.
+   * Switch on SOM type.
+   */
+  type = dn_bufp->dblock.kind;
+  switch (type)
+    {
+    case DNTT_TYPE_SRCFILE:
+      /* This type of symbol indicates from which source file or
+       * include file any following data comes. It may indicate:
+       *
+       * o   The start of an entirely new source file (and thus
+       *     a new module)
+       *
+       * o   The start of a different source file due to #include
+       *
+       * o   The end of an include file and the return to the original
+       *     file. Thus if "foo.c" includes "bar.h", we see first
+       *     a SRCFILE for foo.c, then one for bar.h, and then one for
+       *     foo.c again.
+       *
+       * If it indicates the start of a new module then we must
+       * finish the symbol table of the previous module 
+       * (if any) and start accumulating a new symbol table.  
+       */
+
+      valu = text_offset;
+      if (!last_source_file)
+       {
+         /*
+          * A note on "last_source_file": this is a char* pointing
+          * to the actual file name.  "start_symtab" sets it,
+          * "end_symtab" clears it.
+          *
+          * So if "last_source_file" is NULL, then either this is
+          * the first record we are looking at, or a previous call
+          * to "end_symtab()" was made to close out the previous
+          * module.  Since we're now quitting the scan loop when we
+          * see a MODULE END record, we should never get here, except
+          * in the case that we're not using the quick look-up tables
+          * and have to use the old system as a fall-back.
+          */
+         start_symtab (name, NULL, valu);
+         record_debugformat ("HP");
+         SL_INDEX (objfile) = dn_bufp->dsfile.address;
+       }
+
+      else
+       {
+         /* Either a new include file, or a SRCFILE record
+          * saying we are back in the main source (or out of
+          * a nested include file) again.
+          */
+         SL_INDEX (objfile) = hpread_record_lines (current_subfile,
+                                                   SL_INDEX (objfile),
+                                                   dn_bufp->dsfile.address,
+                                                   objfile, offset);
+       }
+
+      /* A note on "start_subfile".  This routine will check
+       * the name we pass it and look for an existing subfile
+       * of that name.  There's thus only one sub-file for the
+       * actual source (e.g. for "foo.c" in foo.c), despite the
+       * fact that we'll see lots of SRCFILE entries for foo.c
+       * inside foo.c.
+       */
+      start_subfile (name, NULL);
+      break;
+
+    case DNTT_TYPE_MODULE:
+      /*
+       * We no longer ignore DNTT_TYPE_MODULE symbols.  The module 
+       * represents the meaningful semantic structure of a compilation
+       * unit.  We expect to start the psymtab-to-symtab expansion
+       * looking at a MODULE entry, and to end it at the corresponding
+       * END MODULE entry.
+       *
+       *--Begin outdated comments
+       * 
+       * This record signifies the start of a new source module
+       * In C/C++ there is no explicit "module" construct in the language,
+       * but each compilation unit is implicitly a module and they
+       * do emit the DNTT_TYPE_MODULE records.
+       * The end of the module is marked by a matching DNTT_TYPE_END record.
+       *
+       * The reason GDB gets away with ignoring the DNTT_TYPE_MODULE record 
+       * is it notices the DNTT_TYPE_END record for the previous 
+       * module (see comments under DNTT_TYPE_END case), and then treats
+       * the next DNTT_TYPE_SRCFILE record as if it were the module-start record.
+       * (i.e., it makes a start_symtab() call).
+       * This scheme seems a little convoluted, but I'll leave it 
+       * alone on the principle "if it ain't broke don't fix
+       * it". (RT).
+       *
+       *-- End outdated comments
+       */
+
+      valu = text_offset;
+      if (!last_source_file)
+       {
+         /* Start of a new module. We know this because "last_source_file"
+          * is NULL, which can only happen the first time or if we just 
+          * made a call to end_symtab() to close out the previous module.
+          */
+         start_symtab (name, NULL, valu);
+         SL_INDEX (objfile) = dn_bufp->dmodule.address;
+       }
+      else
+       {
+         /* This really shouldn't happen if we're using the quick
+          * look-up tables, as it would mean we'd scanned past an
+          * END MODULE entry.  But if we're not using the tables,
+          * we started the module on the SRCFILE entry, so it's ok.
+          * For now, accept this.
+          */
+         /* warning( "Error expanding psymtab, missed module end, found entry for %s",
+          *           name );
+          */
+         *at_module_boundary_p = -1;
+       }
+
+      start_subfile (name, NULL);
+      break;
+
+    case DNTT_TYPE_FUNCTION:
+    case DNTT_TYPE_ENTRY:
+      /* A function or secondary entry point.  */
+      valu = dn_bufp->dfunc.lowaddr + offset;
+
+      /* Record lines up to this point. */
+      SL_INDEX (objfile) = hpread_record_lines (current_subfile,
+                                               SL_INDEX (objfile),
+                                               dn_bufp->dfunc.address,
+                                               objfile, offset);
+
+      WITHIN_FUNCTION (objfile) = 1;
+      CURRENT_FUNCTION_VALUE (objfile) = valu;
+
+      /* Stack must be empty now.  */
+      if (context_stack_depth != 0)
+       complain (&lbrac_unmatched_complaint, (char *) symnum);
+      new = push_context (0, valu);
+
+      /* Built a type for the function. This includes processing
+       * the symbol records for the function parameters.
+       */
+      SYMBOL_CLASS (sym) = LOC_BLOCK;
+      SYMBOL_TYPE (sym) = hpread_read_function_type (hp_type, dn_bufp, objfile, 1);
+
+      /* The "SYMBOL_NAME" field is expected to be the mangled name
+       * (if any), which we get from the "alias" field of the SOM record
+       * if that exists.
+       */
+      if ((dn_bufp->dfunc.language == HP_LANGUAGE_CPLUSPLUS) &&
+         dn_bufp->dfunc.alias &&       /* has an alias */
+         *(char *) (VT (objfile) + dn_bufp->dfunc.alias))      /* not a null string */
+       SYMBOL_NAME (sym) = VT (objfile) + dn_bufp->dfunc.alias;
+      else
+       SYMBOL_NAME (sym) = VT (objfile) + dn_bufp->dfunc.name;
+
+      /* Special hack to get around HP compilers' insistence on
+       * reporting "main" as "_MAIN_" for C/C++ */
+      if ((strcmp (SYMBOL_NAME (sym), "_MAIN_") == 0) &&
+         (strcmp (VT (objfile) + dn_bufp->dfunc.name, "main") == 0))
+       SYMBOL_NAME (sym) = VT (objfile) + dn_bufp->dfunc.name;
+
+      /* The SYMBOL_CPLUS_DEMANGLED_NAME field is expected to
+       * be the demangled name.
+       */
+      if (dn_bufp->dfunc.language == HP_LANGUAGE_CPLUSPLUS)
+       {
+         /* SYMBOL_INIT_DEMANGLED_NAME is a macro which winds up
+          * calling the demangler in libiberty (cplus_demangle()) to
+          * do the job. This generally does the job, even though
+          * it's intended for the GNU compiler and not the aCC compiler
+          * Note that SYMBOL_INIT_DEMANGLED_NAME calls the
+          * demangler with arguments DMGL_PARAMS | DMGL_ANSI.
+          * Generally, we don't want params when we display
+          * a demangled name, but when I took out the DMGL_PARAMS,
+          * some things broke, so I'm leaving it in here, and
+          * working around the issue in stack.c. - RT
+          */
+         SYMBOL_INIT_DEMANGLED_NAME (sym, &objfile->symbol_obstack);
+         if ((SYMBOL_NAME (sym) == VT (objfile) + dn_bufp->dfunc.alias) &&
+             (!SYMBOL_CPLUS_DEMANGLED_NAME (sym)))
+           {
+
+             /* Well, the symbol name is mangled, but the
+              * demangler in libiberty failed so the demangled
+              * field is still NULL. Try to
+              * do the job ourselves based on the "name" field
+              * in the SOM record. A complication here is that
+              * the name field contains only the function name
+              * (like "f"), whereas we want the class qualification
+              * (as in "c::f"). Try to reconstruct that.
+              */
+             char *basename;
+             char *classname;
+             char *dem_name;
+             basename = VT (objfile) + dn_bufp->dfunc.name;
+             classname = class_of (SYMBOL_TYPE (sym));
+             if (classname)
+               {
+                 dem_name = xmalloc (strlen (basename) + strlen (classname) + 3);
+                 strcpy (dem_name, classname);
+                 strcat (dem_name, "::");
+                 strcat (dem_name, basename);
+                 SYMBOL_CPLUS_DEMANGLED_NAME (sym) = dem_name;
+                 SYMBOL_LANGUAGE (sym) = language_cplus;
+               }
+           }
+       }
+
+      /* Add the function symbol to the list of symbols in this blockvector */
+      if (dn_bufp->dfunc.global)
+       add_symbol_to_list (sym, &global_symbols);
+      else
+       add_symbol_to_list (sym, &file_symbols);
+      new->name = sym;
+
+      /* Search forward to the next BEGIN and also read
+       * in the line info up to that point. 
+       * Not sure why this is needed.
+       * In HP FORTRAN this code is harmful since there   
+       * may not be a BEGIN after the FUNCTION.
+       * So I made it C/C++ specific. - RT
+       */
+      if (dn_bufp->dfunc.language == HP_LANGUAGE_C ||
+         dn_bufp->dfunc.language == HP_LANGUAGE_CPLUSPLUS)
+       {
+         while (dn_bufp->dblock.kind != DNTT_TYPE_BEGIN)
+           {
+             dn_bufp = hpread_get_lntt (++index, objfile);
+             if (dn_bufp->dblock.extension)
+               continue;
+           }
+         SL_INDEX (objfile) = hpread_record_lines (current_subfile,
+                                                   SL_INDEX (objfile),
+                                                   dn_bufp->dbegin.address,
+                                                   objfile, offset);
+         SYMBOL_LINE (sym) = hpread_get_line (dn_bufp->dbegin.address, objfile);
+       }
+      record_line (current_subfile, SYMBOL_LINE (sym), valu);
+      break;
+
+    case DNTT_TYPE_DOC_FUNCTION:
+      valu = dn_bufp->ddocfunc.lowaddr + offset;
+
+      /* Record lines up to this point. */
+      SL_INDEX (objfile) = hpread_record_lines (current_subfile,
+                                               SL_INDEX (objfile),
+                                               dn_bufp->ddocfunc.address,
+                                               objfile, offset);
+
+      WITHIN_FUNCTION (objfile) = 1;
+      CURRENT_FUNCTION_VALUE (objfile) = valu;
+      /* Stack must be empty now.  */
+      if (context_stack_depth != 0)
+       complain (&lbrac_unmatched_complaint, (char *) symnum);
+      new = push_context (0, valu);
+
+      /* Built a type for the function. This includes processing
+       * the symbol records for the function parameters.
+       */
+      SYMBOL_CLASS (sym) = LOC_BLOCK;
+      SYMBOL_TYPE (sym) = hpread_read_doc_function_type (hp_type, dn_bufp, objfile, 1);
+
+      /* The "SYMBOL_NAME" field is expected to be the mangled name
+       * (if any), which we get from the "alias" field of the SOM record
+       * if that exists.
+       */
+      if ((dn_bufp->ddocfunc.language == HP_LANGUAGE_CPLUSPLUS) &&
+         dn_bufp->ddocfunc.alias &&    /* has an alias */
+         *(char *) (VT (objfile) + dn_bufp->ddocfunc.alias))   /* not a null string */
+       SYMBOL_NAME (sym) = VT (objfile) + dn_bufp->ddocfunc.alias;
+      else
+       SYMBOL_NAME (sym) = VT (objfile) + dn_bufp->ddocfunc.name;
+
+      /* Special hack to get around HP compilers' insistence on
+       * reporting "main" as "_MAIN_" for C/C++ */
+      if ((strcmp (SYMBOL_NAME (sym), "_MAIN_") == 0) &&
+         (strcmp (VT (objfile) + dn_bufp->ddocfunc.name, "main") == 0))
+       SYMBOL_NAME (sym) = VT (objfile) + dn_bufp->ddocfunc.name;
+
+      if (dn_bufp->ddocfunc.language == HP_LANGUAGE_CPLUSPLUS)
+       {
+
+         /* SYMBOL_INIT_DEMANGLED_NAME is a macro which winds up
+          * calling the demangler in libiberty (cplus_demangle()) to
+          * do the job. This generally does the job, even though
+          * it's intended for the GNU compiler and not the aCC compiler
+          * Note that SYMBOL_INIT_DEMANGLED_NAME calls the
+          * demangler with arguments DMGL_PARAMS | DMGL_ANSI.
+          * Generally, we don't want params when we display
+          * a demangled name, but when I took out the DMGL_PARAMS,
+          * some things broke, so I'm leaving it in here, and
+          * working around the issue in stack.c. - RT 
+          */
+         SYMBOL_INIT_DEMANGLED_NAME (sym, &objfile->symbol_obstack);
+
+         if ((SYMBOL_NAME (sym) == VT (objfile) + dn_bufp->ddocfunc.alias) &&
+             (!SYMBOL_CPLUS_DEMANGLED_NAME (sym)))
+           {
+
+             /* Well, the symbol name is mangled, but the
+              * demangler in libiberty failed so the demangled
+              * field is still NULL. Try to
+              * do the job ourselves based on the "name" field
+              * in the SOM record. A complication here is that
+              * the name field contains only the function name
+              * (like "f"), whereas we want the class qualification
+              * (as in "c::f"). Try to reconstruct that.
+              */
+             char *basename;
+             char *classname;
+             char *dem_name;
+             basename = VT (objfile) + dn_bufp->ddocfunc.name;
+             classname = class_of (SYMBOL_TYPE (sym));
+             if (classname)
+               {
+                 dem_name = xmalloc (strlen (basename) + strlen (classname) + 3);
+                 strcpy (dem_name, classname);
+                 strcat (dem_name, "::");
+                 strcat (dem_name, basename);
+                 SYMBOL_CPLUS_DEMANGLED_NAME (sym) = dem_name;
+                 SYMBOL_LANGUAGE (sym) = language_cplus;
+               }
+           }
+       }
+
+      /* Add the function symbol to the list of symbols in this blockvector */
+      if (dn_bufp->ddocfunc.global)
+       add_symbol_to_list (sym, &global_symbols);
+      else
+       add_symbol_to_list (sym, &file_symbols);
+      new->name = sym;
+
+      /* Search forward to the next BEGIN and also read
+       * in the line info up to that point. 
+       * Not sure why this is needed.
+       * In HP FORTRAN this code is harmful since there   
+       * may not be a BEGIN after the FUNCTION.
+       * So I made it C/C++ specific. - RT
+       */
+      if (dn_bufp->ddocfunc.language == HP_LANGUAGE_C ||
+         dn_bufp->ddocfunc.language == HP_LANGUAGE_CPLUSPLUS)
+       {
+         while (dn_bufp->dblock.kind != DNTT_TYPE_BEGIN)
+           {
+             dn_bufp = hpread_get_lntt (++index, objfile);
+             if (dn_bufp->dblock.extension)
+               continue;
+           }
+         SL_INDEX (objfile) = hpread_record_lines (current_subfile,
+                                                   SL_INDEX (objfile),
+                                                   dn_bufp->dbegin.address,
+                                                   objfile, offset);
+         SYMBOL_LINE (sym) = hpread_get_line (dn_bufp->dbegin.address, objfile);
+       }
+      record_line (current_subfile, SYMBOL_LINE (sym), valu);
+      break;
+
+    case DNTT_TYPE_BEGIN:
+      /* Begin a new scope. */
+      if (context_stack_depth == 1 /* this means we're at function level */  &&
+         context_stack[0].name != NULL /* this means it's a function */  &&
+         context_stack[0].depth == 0   /* this means it's the first BEGIN 
+                                          we've seen after the FUNCTION */
+       )
+       {
+         /* This is the first BEGIN after a FUNCTION.
+          * We ignore this one, since HP compilers always insert
+          * at least one BEGIN, i.e. it's:
+          * 
+          *     FUNCTION
+          *     argument symbols
+          *     BEGIN
+          *     local symbols
+          *        (possibly nested BEGIN ... END's if there are inner { } blocks)
+          *     END
+          *     END
+          *
+          * By ignoring this first BEGIN, the local symbols get treated
+          * as belonging to the function scope, and "print func::local_sym"
+          * works (which is what we want).
+          */
+
+         /* All we do here is increase the depth count associated with
+          * the FUNCTION entry in the context stack. This ensures that
+          * the next BEGIN we see (if any), representing a real nested { }
+          * block, will get processed.
+          */
+
+         context_stack[0].depth++;
+
+       }
+      else
+       {
+
+         /* Record lines up to this SLT pointer. */
+         SL_INDEX (objfile) = hpread_record_lines (current_subfile,
+                                                   SL_INDEX (objfile),
+                                                   dn_bufp->dbegin.address,
+                                                   objfile, offset);
+         /* Calculate start address of new scope */
+         valu = hpread_get_location (dn_bufp->dbegin.address, objfile);
+         valu += offset;       /* Relocate for dynamic loading */
+         /* We use the scope start DNTT index as nesting depth identifier! */
+         desc = hpread_get_scope_start (dn_bufp->dbegin.address, objfile);
+         new = push_context (desc, valu);
+       }
+      break;
+
+    case DNTT_TYPE_END:
+      /* End a scope.  */
+
+      /* Valid end kinds are:
+       *  MODULE
+       *  FUNCTION
+       *  WITH
+       *  COMMON
+       *  BEGIN
+       *  CLASS_SCOPE
+       */
+
+      SL_INDEX (objfile) = hpread_record_lines (current_subfile,
+                                               SL_INDEX (objfile),
+                                               dn_bufp->dend.address,
+                                               objfile, offset);
+      switch (dn_bufp->dend.endkind)
+       {
+       case DNTT_TYPE_MODULE:
+         /* Ending a module ends the symbol table for that module.  
+          * Calling end_symtab() has the side effect of clearing the
+          * last_source_file pointer, which in turn signals 
+          * process_one_debug_symbol() to treat the next DNTT_TYPE_SRCFILE
+          * record as a module-begin.
+          */
+         valu = text_offset + text_size + offset;
+
+         /* Tell our caller that we're done with expanding the
+          * debug information for a module.
+          */
+         *at_module_boundary_p = 1;
+
+         /* Don't do this, as our caller will do it!
+
+          *      (void) end_symtab (valu, objfile, 0);
+          */
+         break;
+
+       case DNTT_TYPE_FUNCTION:
+         /* Ending a function, well, ends the function's scope.  */
+         dn_temp = hpread_get_lntt (dn_bufp->dend.beginscope.dnttp.index,
+                                    objfile);
+         valu = dn_temp->dfunc.hiaddr + offset;
+         /* Insert func params into local list */
+         merge_symbol_lists (&param_symbols, &local_symbols);
+         new = pop_context ();
+         /* Make a block for the local symbols within.  */
+         finish_block (new->name, &local_symbols, new->old_blocks,
+                       new->start_addr, valu, objfile);
+         WITHIN_FUNCTION (objfile) = 0;        /* This may have to change for Pascal */
+         local_symbols = new->locals;
+         param_symbols = new->params;
+         break;
+
+       case DNTT_TYPE_BEGIN:
+         if (context_stack_depth == 1 &&
+             context_stack[0].name != NULL &&
+             context_stack[0].depth == 1)
+           {
+             /* This is the END corresponding to the
+              * BEGIN which we ignored - see DNTT_TYPE_BEGIN case above.
+              */
+             context_stack[0].depth--;
+           }
+         else
+           {
+             /* Ending a local scope.  */
+             valu = hpread_get_location (dn_bufp->dend.address, objfile);
+             /* Why in the hell is this needed?  */
+             valu += offset + 9;       /* Relocate for dynamic loading */
+             new = pop_context ();
+             desc = dn_bufp->dend.beginscope.dnttp.index;
+             if (desc != new->depth)
+               complain (&lbrac_mismatch_complaint, (char *) symnum);
+
+             /* Make a block for the local symbols within.  */
+             finish_block (new->name, &local_symbols, new->old_blocks,
+                           new->start_addr, valu, objfile);
+             local_symbols = new->locals;
+             param_symbols = new->params;
+           }
+         break;
+
+       case DNTT_TYPE_WITH:
+         /* Since we ignore the DNTT_TYPE_WITH that starts the scope,
+          * we can ignore the DNTT_TYPE_END that ends it.
+          */
+         break;
+
+       case DNTT_TYPE_COMMON:
+         /* End a FORTRAN common block. We don't currently handle these */
+         complain (&hpread_unhandled_end_common_complaint);
+         break;
+
+       case DNTT_TYPE_CLASS_SCOPE:
+
+         /* pai: FIXME Not handling nested classes for now -- must
+            * maintain a stack */
+         class_scope_name = NULL;
+
+#if 0
+         /* End a class scope */
+         valu = hpread_get_location (dn_bufp->dend.address, objfile);
+         /* Why in the hell is this needed?  */
+         valu += offset + 9;   /* Relocate for dynamic loading */
+         new = pop_context ();
+         desc = dn_bufp->dend.beginscope.dnttp.index;
+         if (desc != new->depth)
+           complain (&lbrac_mismatch_complaint, (char *) symnum);
+         /* Make a block for the local symbols within.  */
+         finish_block (new->name, &local_symbols, new->old_blocks,
+                       new->start_addr, valu, objfile);
+         local_symbols = new->locals;
+         param_symbols = new->params;
+#endif
+         break;
+
+       default:
+         complain (&hpread_unexpected_end_complaint);
+         break;
+       }
+      break;
+
+      /* DNTT_TYPE_IMPORT is not handled */
+
+    case DNTT_TYPE_LABEL:
+      SYMBOL_NAMESPACE (sym) = LABEL_NAMESPACE;
+      break;
+
+    case DNTT_TYPE_FPARAM:
+      /* Function parameters.  */
+      /* Note 1: This code was present in the 4.16 sources, and then
+         removed, because fparams are handled in
+         hpread_read_function_type().  However, while fparam symbols
+         are indeed handled twice, this code here cannot be removed
+         because then they don't get added to the local symbol list of
+         the function's code block, which leads to a failure to look
+         up locals, "this"-relative member names, etc.  So I've put
+         this code back in. pai/1997-07-21 */
+      /* Note 2: To fix a defect, we stopped adding FPARAMS to local_symbols
+         in hpread_read_function_type(), so FPARAMS had to be handled
+         here.  I changed the location to be the appropriate argument
+         kinds rather than LOC_LOCAL. pai/1997-08-08 */
+      /* Note 3: Well, the fix in Note 2 above broke argument printing
+         in traceback frames, and further it makes assumptions about the
+         order of the FPARAM entries from HP compilers (cc and aCC in particular
+         generate them in reverse orders -- fixing one breaks for the other).
+         So I've added code in hpread_read_function_type() to add fparams
+         to a param_symbols list for the current context level.  These are
+         then merged into local_symbols when a function end is reached.
+         pai/1997-08-11 */
+
+      break;                   /* do nothing; handled in hpread_read_function_type() */
+
+#if 0                          /* Old code */
+      if (dn_bufp->dfparam.regparam)
+       SYMBOL_CLASS (sym) = LOC_REGISTER;
+      else if (dn_bufp->dfparam.indirect)
+       SYMBOL_CLASS (sym) = LOC_REF_ARG;
+      else
+       SYMBOL_CLASS (sym) = LOC_ARG;
+      SYMBOL_NAMESPACE (sym) = VAR_NAMESPACE;
+      if (dn_bufp->dfparam.copyparam)
+       {
+         SYMBOL_VALUE (sym) = dn_bufp->dfparam.location;
+#ifdef HPREAD_ADJUST_STACK_ADDRESS
+         SYMBOL_VALUE (sym)
+           += HPREAD_ADJUST_STACK_ADDRESS (CURRENT_FUNCTION_VALUE (objfile));
+#endif
+       }
+      else
+       SYMBOL_VALUE (sym) = dn_bufp->dfparam.location;
+      SYMBOL_TYPE (sym) = hpread_type_lookup (dn_bufp->dfparam.type, objfile);
+      add_symbol_to_list (sym, &fparam_symbols);
+      break;
+#endif
+
+    case DNTT_TYPE_SVAR:
+      /* Static variables.  */
+      SYMBOL_CLASS (sym) = LOC_STATIC;
+
+      /* Note: There is a case that arises with globals in shared
+       * libraries where we need to set the address to LOC_INDIRECT.
+       * This case is if you have a global "g" in one library, and
+       * it is referenced "extern <type> g;" in another library.
+       * If we're processing the symbols for the referencing library,
+       * we'll see a global "g", but in this case the address given
+       * in the symbol table contains a pointer to the real "g".
+       * We use the storage class LOC_INDIRECT to indicate this. RT
+       */
+      if (is_in_import_list (SYMBOL_NAME (sym), objfile))
+       SYMBOL_CLASS (sym) = LOC_INDIRECT;
+
+      SYMBOL_VALUE_ADDRESS (sym) = dn_bufp->dsvar.location + data_offset;
+      SYMBOL_TYPE (sym) = hpread_type_lookup (dn_bufp->dsvar.type, objfile);
+
+      if (dn_bufp->dsvar.global)
+       add_symbol_to_list (sym, &global_symbols);
+
+      else if (WITHIN_FUNCTION (objfile))
+       add_symbol_to_list (sym, &local_symbols);
+
+      else
+       add_symbol_to_list (sym, &file_symbols);
+
+      if (dn_bufp->dsvar.thread_specific)
+       {
+         /* Thread-local variable.
+          */
+         SYMBOL_CLASS (sym) = LOC_THREAD_LOCAL_STATIC;
+         SYMBOL_BASEREG (sym) = CR27_REGNUM;
+
+         if (objfile->flags & OBJF_SHARED)
+           {
+             /*
+              * This variable is not only thread local but
+              * in a shared library.
+              *
+              * Alas, the shared lib structures are private
+              * to "somsolib.c".  But C lets us point to one.
+              */
+             struct so_list *so;
+
+             if (objfile->obj_private == NULL)
+               error ("Internal error in reading shared library information.");
+
+             so = ((obj_private_data_t *) (objfile->obj_private))->so_info;
+             if (so == NULL)
+               error ("Internal error in reading shared library information.");
+
+             /* Thread-locals in shared libraries do NOT have the
+              * standard offset ("data_offset"), so we re-calculate
+              * where to look for this variable, using a call-back
+              * to interpret the private shared-library data.
+              */
+             SYMBOL_VALUE_ADDRESS (sym) = dn_bufp->dsvar.location +
+               so_lib_thread_start_addr (so);
+           }
+       }
+      break;
+
+    case DNTT_TYPE_DVAR:
+      /* Dynamic variables.  */
+      if (dn_bufp->ddvar.regvar)
+       SYMBOL_CLASS (sym) = LOC_REGISTER;
+      else
+       SYMBOL_CLASS (sym) = LOC_LOCAL;
+
+      SYMBOL_VALUE (sym) = dn_bufp->ddvar.location;
+#ifdef HPREAD_ADJUST_STACK_ADDRESS
+      SYMBOL_VALUE (sym)
+       += HPREAD_ADJUST_STACK_ADDRESS (CURRENT_FUNCTION_VALUE (objfile));
+#endif
+      SYMBOL_TYPE (sym) = hpread_type_lookup (dn_bufp->ddvar.type, objfile);
+      if (dn_bufp->ddvar.global)
+       add_symbol_to_list (sym, &global_symbols);
+      else if (WITHIN_FUNCTION (objfile))
+       add_symbol_to_list (sym, &local_symbols);
+      else
+       add_symbol_to_list (sym, &file_symbols);
+      break;
+
+    case DNTT_TYPE_CONST:
+      /* A constant (pascal?).  */
+      SYMBOL_CLASS (sym) = LOC_CONST;
+      SYMBOL_VALUE (sym) = dn_bufp->dconst.location;
+      SYMBOL_TYPE (sym) = hpread_type_lookup (dn_bufp->dconst.type, objfile);
+      if (dn_bufp->dconst.global)
+       add_symbol_to_list (sym, &global_symbols);
+      else if (WITHIN_FUNCTION (objfile))
+       add_symbol_to_list (sym, &local_symbols);
+      else
+       add_symbol_to_list (sym, &file_symbols);
+      break;
+
+    case DNTT_TYPE_TYPEDEF:
+      /* A typedef. We do want to process these, since a name is
+       * added to the namespace for the typedef'ed name.
+       */
+      SYMBOL_NAMESPACE (sym) = VAR_NAMESPACE;
+      SYMBOL_TYPE (sym) = hpread_type_lookup (dn_bufp->dtype.type, objfile);
+      if (dn_bufp->dtype.global)
+       add_symbol_to_list (sym, &global_symbols);
+      else if (WITHIN_FUNCTION (objfile))
+       add_symbol_to_list (sym, &local_symbols);
+      else
+       add_symbol_to_list (sym, &file_symbols);
+      break;
+
+    case DNTT_TYPE_TAGDEF:
+      {
+       int global = dn_bufp->dtag.global;
+       /* Structure, union, enum, template, or class tag definition */
+       /* We do want to process these, since a name is
+        * added to the namespace for the tag name (and if C++ class,
+        * for the typename also).
+        */
+       SYMBOL_NAMESPACE (sym) = STRUCT_NAMESPACE;
+
+       /* The tag contains in its "type" field a pointer to the
+        * DNTT_TYPE_STRUCT, DNTT_TYPE_UNION, DNTT_TYPE_ENUM, 
+        * DNTT_TYPE_CLASS or DNTT_TYPE_TEMPLATE
+        * record that actually defines the type.
+        */
+       SYMBOL_TYPE (sym) = hpread_type_lookup (dn_bufp->dtype.type, objfile);
+       TYPE_NAME (sym->type) = SYMBOL_NAME (sym);
+       TYPE_TAG_NAME (sym->type) = SYMBOL_NAME (sym);
+       if (dn_bufp->dtag.global)
+         add_symbol_to_list (sym, &global_symbols);
+       else if (WITHIN_FUNCTION (objfile))
+         add_symbol_to_list (sym, &local_symbols);
+       else
+         add_symbol_to_list (sym, &file_symbols);
+
+       /* If this is a C++ class, then we additionally 
+        * need to define a typedef for the
+        * class type. E.g., so that the name "c" becomes visible as
+        * a type name when the user says "class c { ... }".
+        * In order to figure this out, we need to chase down the "type"
+        * field to get to the DNTT_TYPE_CLASS record. 
+        *
+        * We also add the typename for ENUM. Though this isn't
+        * strictly correct, it is necessary because of the debug info
+        * generated by the aCC compiler, in which we cannot
+        * distinguish between:
+        *   enum e { ... };
+        * and
+        *   typedef enum { ... } e;
+        * I.e., the compiler emits the same debug info for the above
+        * two cases, in both cases "e" appearing as a tagdef.
+        * Therefore go ahead and generate the typename so that
+        * "ptype e" will work in the above cases.
+        *
+        * We also add the typename for TEMPLATE, so as to allow "ptype t"
+        * when "t" is a template name. 
+        */
+       if (dn_bufp->dtype.type.dnttp.index < LNTT_SYMCOUNT (objfile))
+         dn_bufp = hpread_get_lntt (dn_bufp->dtag.type.dnttp.index, objfile);
+       else
+         {
+           complain (&hpread_tagdef_complaint);
+           return;
+         }
+       if (dn_bufp->dblock.kind == DNTT_TYPE_CLASS ||
+           dn_bufp->dblock.kind == DNTT_TYPE_ENUM ||
+           dn_bufp->dblock.kind == DNTT_TYPE_TEMPLATE)
+         {
+           struct symbol *newsym;
+
+           newsym = (struct symbol *) obstack_alloc (&objfile->symbol_obstack,
+                                                   sizeof (struct symbol));
+           memset (newsym, 0, sizeof (struct symbol));
+           SYMBOL_NAME (newsym) = name;
+           SYMBOL_LANGUAGE (newsym) = language_auto;
+           SYMBOL_NAMESPACE (newsym) = VAR_NAMESPACE;
+           SYMBOL_LINE (newsym) = 0;
+           SYMBOL_VALUE (newsym) = 0;
+           SYMBOL_CLASS (newsym) = LOC_TYPEDEF;
+           SYMBOL_TYPE (newsym) = sym->type;
+           if (global)
+             add_symbol_to_list (newsym, &global_symbols);
+           else if (WITHIN_FUNCTION (objfile))
+             add_symbol_to_list (newsym, &local_symbols);
+           else
+             add_symbol_to_list (newsym, &file_symbols);
+         }
+      }
+      break;
+
+    case DNTT_TYPE_POINTER:
+      /* Declares a pointer type. Should not be necessary to do anything
+       * with the type at this level; these are processed
+       * at the hpread_type_lookup() level. 
+       */
+      break;
+
+    case DNTT_TYPE_ENUM:
+      /* Declares an enum type. Should not be necessary to do anything
+       * with the type at this level; these are processed
+       * at the hpread_type_lookup() level. 
+       */
+      break;
+
+    case DNTT_TYPE_MEMENUM:
+      /* Member of enum */
+      /* Ignored at this level, but hpread_read_enum_type() will take
+       * care of walking the list of enumeration members.
+       */
+      break;
+
+    case DNTT_TYPE_SET:
+      /* Declares a set type. Should not be necessary to do anything
+       * with the type at this level; these are processed
+       * at the hpread_type_lookup() level. 
+       */
+      break;
+
+    case DNTT_TYPE_SUBRANGE:
+      /* Declares a subrange type. Should not be necessary to do anything
+       * with the type at this level; these are processed
+       * at the hpread_type_lookup() level. 
+       */
+      break;
+
+    case DNTT_TYPE_ARRAY:
+      /* Declares an array type. Should not be necessary to do anything
+       * with the type at this level; these are processed
+       * at the hpread_type_lookup() level. 
+       */
+      break;
+
+    case DNTT_TYPE_STRUCT:
+    case DNTT_TYPE_UNION:
+      /* Declares an struct/union type. 
+       * Should not be necessary to do anything
+       * with the type at this level; these are processed
+       * at the hpread_type_lookup() level. 
+       */
+      break;
+
+    case DNTT_TYPE_FIELD:
+      /* Structure/union/class field */
+      /* Ignored at this level, but hpread_read_struct_type() will take
+       * care of walking the list of structure/union/class members.
+       */
+      break;
+
+      /* DNTT_TYPE_VARIANT is not handled by GDB */
+
+      /* DNTT_TYPE_FILE is not handled by GDB */
+
+    case DNTT_TYPE_FUNCTYPE:
+      /* Function type */
+      /* Ignored at this level, handled within hpread_type_lookup() */
+      break;
+
+    case DNTT_TYPE_WITH:
+      /* This is emitted within methods to indicate "with <class>" 
+       * scoping rules (i.e., indicate that the class data members
+       * are directly visible).
+       * However, since GDB already infers this by looking at the
+       * "this" argument, interpreting the DNTT_TYPE_WITH 
+       * symbol record is unnecessary.
+       */
+      break;
+
+    case DNTT_TYPE_COMMON:
+      /* FORTRAN common. Not yet handled. */
+      complain (&hpread_unhandled_common_complaint);
+      break;
+
+      /* DNTT_TYPE_COBSTRUCT is not handled by GDB.  */
+      /* DNTT_TYPE_XREF is not handled by GDB.  */
+      /* DNTT_TYPE_SA is not handled by GDB.  */
+      /* DNTT_TYPE_MACRO is not handled by GDB */
+
+    case DNTT_TYPE_BLOCKDATA:
+      /* Not sure what this is - part of FORTRAN support maybe? 
+       * Anyway, not yet handled.
+       */
+      complain (&hpread_unhandled_blockdata_complaint);
+      break;
+
+    case DNTT_TYPE_CLASS_SCOPE:
+
+
+
+      /* The compiler brackets member functions with a CLASS_SCOPE/END
+       * pair of records, presumably to put them in a different scope
+       * from the module scope where they are normally defined.
+       * E.g., in the situation:
+       *   void f() { ... }
+       *   void c::f() { ...}
+       * The member function "c::f" will be bracketed by a CLASS_SCOPE/END.
+       * This causes "break f" at the module level to pick the
+       * the file-level function f(), not the member function
+       * (which needs to be referenced via "break c::f"). 
+       * 
+       * Here we record the class name to generate the demangled names of
+       * member functions later.
+       *
+       * FIXME Not being used now for anything -- cplus_demangle seems
+       * enough for getting the class-qualified names of functions. We
+       * may need this for handling nested classes and types.  */
+
+      /* pai: FIXME Not handling nested classes for now -- need to
+       * maintain a stack */
+
+      dn_temp = hpread_get_lntt (dn_bufp->dclass_scope.type.dnttp.index, objfile);
+      if (dn_temp->dblock.kind == DNTT_TYPE_TAGDEF)
+       class_scope_name = VT (objfile) + dn_temp->dtag.name;
+      else
+       class_scope_name = NULL;
+
+#if 0
+
+      /* Begin a new scope.  */
+      SL_INDEX (objfile) = hpread_record_lines (current_subfile,
+                                               SL_INDEX (objfile),
+                                             dn_bufp->dclass_scope.address,
+                                               objfile, offset);
+      valu = hpread_get_location (dn_bufp->dclass_scope.address, objfile);
+      valu += offset;          /* Relocate for dynamic loading */
+      desc = hpread_get_scope_start (dn_bufp->dclass_scope.address, objfile);
+      /* We use the scope start DNTT index as the nesting depth identifier! */
+      new = push_context (desc, valu);
+#endif
+      break;
+
+    case DNTT_TYPE_REFERENCE:
+      /* Declares a C++ reference type. Should not be necessary to do anything
+       * with the type at this level; these are processed
+       * at the hpread_type_lookup() level.
+       */
+      break;
+
+    case DNTT_TYPE_PTRMEM:
+      /* Declares a C++ pointer-to-data-member type. This does not
+       * need to be handled at this level; being a type description it
+       * is instead handled at the hpread_type_lookup() level.
+       */
+      break;
+
+    case DNTT_TYPE_PTRMEMFUNC:
+      /* Declares a C++ pointer-to-function-member type. This does not
+       * need to be handled at this level; being a type description it
+       * is instead handled at the hpread_type_lookup() level.
+       */
+      break;
+
+    case DNTT_TYPE_CLASS:
+      /* Declares a class type. 
+       * Should not be necessary to do anything
+       * with the type at this level; these are processed
+       * at the hpread_type_lookup() level. 
+       */
+      break;
+
+    case DNTT_TYPE_GENFIELD:
+      /* I believe this is used for class member functions */
+      /* Ignored at this level, but hpread_read_struct_type() will take
+       * care of walking the list of class members.
+       */
+      break;
+
+    case DNTT_TYPE_VFUNC:
+      /* Virtual function */
+      /* This does not have to be handled at this level; handled in
+       * the course of processing class symbols.
+       */
+      break;
+
+    case DNTT_TYPE_MEMACCESS:
+      /* DDE ignores this symbol table record.
+       * It has something to do with "modified access" to class members.
+       * I'll assume we can safely ignore it too.
+       */
+      break;
+
+    case DNTT_TYPE_INHERITANCE:
+      /* These don't have to be handled here, since they are handled
+       * within hpread_read_struct_type() in the process of constructing
+       * a class type.
+       */
+      break;
+
+    case DNTT_TYPE_FRIEND_CLASS:
+    case DNTT_TYPE_FRIEND_FUNC:
+      /* These can safely be ignored, as GDB doesn't need this
+       * info. DDE only uses it in "describe". We may later want
+       * to extend GDB's "ptype" to give this info, but for now
+       * it seems safe enough to ignore it.
+       */
+      break;
+
+    case DNTT_TYPE_MODIFIER:
+      /* Intended to supply "modified access" to a type */
+      /* From the way DDE handles this, it looks like it always
+       * modifies a type. Therefore it is safe to ignore it at this
+       * level, and handle it in hpread_type_lookup().
+       */
+      break;
+
+    case DNTT_TYPE_OBJECT_ID:
+      /* Just ignore this - that's all DDE does */
+      break;
+
+    case DNTT_TYPE_MEMFUNC:
+      /* Member function */
+      /* This does not have to be handled at this level; handled in
+       * the course of processing class symbols.
+       */
+      break;
+
+    case DNTT_TYPE_DOC_MEMFUNC:
+      /* Member function */
+      /* This does not have to be handled at this level; handled in
+       * the course of processing class symbols.
+       */
+      break;
+
+    case DNTT_TYPE_TEMPLATE:
+      /* Template - sort of the header for a template definition,
+       * which like a class, points to a member list and also points
+       * to a TEMPLATE_ARG list of type-arguments.
+       * We do not need to process TEMPLATE records at this level though.
+       */
+      break;
+
+    case DNTT_TYPE_TEMPLATE_ARG:
+      /* The TEMPLATE record points to an argument list of
+       * TEMPLATE_ARG records, each of which describes one
+       * of the type-arguments.
+       * We do not need to process TEMPLATE_ARG records at this level though.
+       */
+      break;
+
+    case DNTT_TYPE_FUNC_TEMPLATE:
+      /* This will get emitted for member functions of templates.
+       * But we don't need to process this record at this level though,
+       * we will process it in the course of processing a TEMPLATE
+       * record.
+       */
+      break;
+
+    case DNTT_TYPE_LINK:
+      /* The LINK record is used to link up templates with instantiations. */
+      /* It is not clear why this is needed, and furthermore aCC does
+       * not appear to generate this, so I think we can safely ignore it. - RT
+       */
+      break;
+
+      /* DNTT_TYPE_DYN_ARRAY_DESC is not handled by GDB */
+      /* DNTT_TYPE_DESC_SUBRANGE is not handled by GDB */
+      /* DNTT_TYPE_BEGIN_EXT is not handled by GDB */
+      /* DNTT_TYPE_INLN is not handled by GDB */
+      /* DNTT_TYPE_INLN_LIST is not handled by GDB */
+      /* DNTT_TYPE_ALIAS is not handled by GDB */
+
+    default:
+      break;
+    }
+}
+
+/* Get nesting depth for a DNTT entry.
+ * DN_BUFP points to a DNTT entry.
+ * OBJFILE is the object file.
+ * REPORT_NESTED is a flag; if 0, real nesting depth is
+ * reported, if it is 1, the function simply returns a 
+ * non-zero value if the nesting depth is anything > 0.
+ * 
+ * Return value is an integer.  0 => not a local type / name
+ * positive return => type or name is local to some 
+ * block or function.
+ */
+
+
+/* elz: ATTENTION: FIXME: NOTE: WARNING!!!!
+   this function now returns 0 right away. It was taking too much time
+   at start up. Now, though, the local types are not handled correctly.
+ */
+
+
+static int
+hpread_get_scope_depth (union dnttentry *dn_bufp, struct objfile *objfile,
+                       int report_nested)
+{
+  register int index;
+  register union dnttentry *dn_tmp;
+  register short depth = 0;
+/****************************/
+  return 0;
+/****************************/
+
+  index = (((char *) dn_bufp) - LNTT (objfile)) / (sizeof (struct dntt_type_block));
+
+  while (--index >= 0)
+    {
+      dn_tmp = hpread_get_lntt (index, objfile);
+      switch (dn_tmp->dblock.kind)
+       {
+       case DNTT_TYPE_MODULE:
+         return depth;
+       case DNTT_TYPE_END:
+         /* index is signed int; dnttp.index is 29-bit unsigned int! */
+         index = (int) dn_tmp->dend.beginscope.dnttp.index;
+         break;
+       case DNTT_TYPE_BEGIN:
+       case DNTT_TYPE_FUNCTION:
+       case DNTT_TYPE_DOC_FUNCTION:
+       case DNTT_TYPE_WITH:
+       case DNTT_TYPE_COMMON:
+       case DNTT_TYPE_CLASS_SCOPE:
+         depth++;
+         if (report_nested)
+           return 1;
+         break;
+       default:
+         break;
+       }
+    }
+  return depth;
+}
+
+/* Adjust the bitoffsets for all fields of an anonymous union of
+   type TYPE by negative BITS.  This handles HP aCC's hideous habit
+   of giving members of anonymous unions bit offsets relative to the
+   enclosing structure instead of relative to the union itself. */
+
+static void
+hpread_adjust_bitoffsets (struct type *type, int bits)
+{
+  register int i;
+
+  /* This is done only for unions; caller had better check that
+     it is an anonymous one. */
+  if (TYPE_CODE (type) != TYPE_CODE_UNION)
+    return;
+
+  /* Adjust each field; since this is a union, there are no base
+     classes. Also no static membes.  Also, no need for recursion as
+     the members of this union if themeselves structs or unions, have
+     the correct bitoffsets; if an anonymous union is a member of this
+     anonymous union, the code in hpread_read_struct_type() will
+     adjust for that. */
+
+  for (i = 0; i < TYPE_NFIELDS (type); i++)
+    TYPE_FIELD_BITPOS (type, i) -= bits;
+}
+
+/* Because of quirks in HP compilers' treatment of anonymous unions inside
+   classes, we have to chase through a chain of threaded FIELD entries.
+   If we encounter an anonymous union in the chain, we must recursively skip over
+   that too.
+
+   This function does a "next" in the chain of FIELD entries, but transparently
+   skips over anonymous unions' fields (recursively).
+
+   Inputs are the number of times to do "next" at the top level, the dnttpointer
+   (FIELD) and entry pointer (FIELDP) for the dntt record corresponding to it,
+   and the ubiquitous objfile parameter. (Note: FIELDP is a **.)  Return value
+   is a dnttpointer for the new field after all the skipped ones */
+
+static dnttpointer
+hpread_get_next_skip_over_anon_unions (int skip_fields, dnttpointer field,
+                                      union dnttentry **fieldp,
+                                      struct objfile *objfile)
+{
+  struct type *anon_type;
+  register int i;
+  int bitoffset;
+  char *name;
+
+  for (i = 0; i < skip_fields; i++)
+    {
+      /* Get type of item we're looking at now; recursively processes the types
+         of these intermediate items we skip over, so they aren't lost. */
+      anon_type = hpread_type_lookup ((*fieldp)->dfield.type, objfile);
+      anon_type = CHECK_TYPEDEF (anon_type);
+      bitoffset = (*fieldp)->dfield.bitoffset;
+      name = VT (objfile) + (*fieldp)->dfield.name;
+      /* First skip over one item to avoid stack death on recursion */
+      field = (*fieldp)->dfield.nextfield;
+      *fieldp = hpread_get_lntt (field.dnttp.index, objfile);
+      /* Do we have another anonymous union? If so, adjust the bitoffsets
+         of its members and skip over its members. */
+      if ((TYPE_CODE (anon_type) == TYPE_CODE_UNION) &&
+         (!name || STREQ (name, "")))
+       {
+         hpread_adjust_bitoffsets (anon_type, bitoffset);
+         field = hpread_get_next_skip_over_anon_unions (TYPE_NFIELDS (anon_type), field, fieldp, objfile);
+       }
+    }
+  return field;
+}
diff --git a/gdb/mdebugread.c b/gdb/mdebugread.c
new file mode 100644 (file)
index 0000000..1695afd
--- /dev/null
@@ -0,0 +1,5021 @@
+/* Read a symbol table in ECOFF format (Third-Eye).
+   Copyright 1986, 1987, 1989, 1990, 1991, 1992, 1993, 1994, 1995, 1996,
+   1997, 1998, 1999, 2000, 2001, 2002
+   Free Software Foundation, Inc.
+   Original version contributed by Alessandro Forin (af@cs.cmu.edu) at
+   CMU.  Major work by Per Bothner, John Gilmore and Ian Lance Taylor
+   at Cygnus Support.
+
+   This file is part of GDB.
+
+   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 module provides the function mdebug_build_psymtabs.  It reads
+   ECOFF debugging information into partial symbol tables.  The
+   debugging information is read from two structures.  A struct
+   ecoff_debug_swap includes the sizes of each ECOFF structure and
+   swapping routines; these are fixed for a particular target.  A
+   struct ecoff_debug_info points to the debugging information for a
+   particular object file.
+
+   ECOFF symbol tables are mostly written in the byte order of the
+   target machine.  However, one section of the table (the auxiliary
+   symbol information) is written in the host byte order.  There is a
+   bit in the other symbol info which describes which host byte order
+   was used.  ECOFF thereby takes the trophy from Intel `b.out' for
+   the most brain-dead adaptation of a file format to byte order.
+
+   This module can read all four of the known byte-order combinations,
+   on any type of host.  */
+
+#include "defs.h"
+#include "symtab.h"
+#include "gdbtypes.h"
+#include "gdbcore.h"
+#include "symfile.h"
+#include "objfiles.h"
+#include "gdb_obstack.h"
+#include "buildsym.h"
+#include "stabsread.h"
+#include "complaints.h"
+#include "demangle.h"
+#include "gdb_assert.h"
+
+/* These are needed if the tm.h file does not contain the necessary
+   mips specific definitions.  */
+
+#ifndef MIPS_EFI_SYMBOL_NAME
+#define MIPS_EFI_SYMBOL_NAME "__GDB_EFI_INFO__"
+extern void ecoff_relocate_efi (struct symbol *, CORE_ADDR);
+#include "coff/sym.h"
+#include "coff/symconst.h"
+typedef struct mips_extra_func_info
+  {
+    long numargs;
+    PDR pdr;
+  }
+ *mips_extra_func_info_t;
+#ifndef RA_REGNUM
+#define RA_REGNUM 0
+#endif
+#endif
+
+#ifdef USG
+#include <sys/types.h>
+#endif
+
+#include "gdb_stat.h"
+#include "gdb_string.h"
+
+#include "bfd.h"
+
+#include "coff/ecoff.h"                /* COFF-like aspects of ecoff files */
+
+#include "libaout.h"           /* Private BFD a.out information.  */
+#include "aout/aout64.h"
+#include "aout/stab_gnu.h"     /* STABS information */
+
+#include "expression.h"
+#include "language.h"          /* For local_hex_string() */
+
+extern void _initialize_mdebugread (void);
+
+/* Provide a way to test if we have both ECOFF and ELF symbol tables.  
+   We use this define in order to know whether we should override a 
+   symbol's ECOFF section with its ELF section.  This is necessary in 
+   case the symbol's ELF section could not be represented in ECOFF.  */
+#define ECOFF_IN_ELF(bfd) (bfd_get_flavour (bfd) == bfd_target_elf_flavour \
+                          && bfd_get_section_by_name (bfd, ".mdebug") != NULL)
+\f
+
+/* We put a pointer to this structure in the read_symtab_private field
+   of the psymtab.  */
+
+struct symloc
+  {
+    /* Index of the FDR that this psymtab represents.  */
+    int fdr_idx;
+    /* The BFD that the psymtab was created from.  */
+    bfd *cur_bfd;
+    const struct ecoff_debug_swap *debug_swap;
+    struct ecoff_debug_info *debug_info;
+    struct mdebug_pending **pending_list;
+    /* Pointer to external symbols for this file.  */
+    EXTR *extern_tab;
+    /* Size of extern_tab.  */
+    int extern_count;
+    enum language pst_language;
+  };
+
+#define PST_PRIVATE(p) ((struct symloc *)(p)->read_symtab_private)
+#define FDR_IDX(p) (PST_PRIVATE(p)->fdr_idx)
+#define CUR_BFD(p) (PST_PRIVATE(p)->cur_bfd)
+#define DEBUG_SWAP(p) (PST_PRIVATE(p)->debug_swap)
+#define DEBUG_INFO(p) (PST_PRIVATE(p)->debug_info)
+#define PENDING_LIST(p) (PST_PRIVATE(p)->pending_list)
+
+#define SC_IS_TEXT(sc) ((sc) == scText \
+                  || (sc) == scRConst \
+                  || (sc) == scInit \
+                  || (sc) == scFini)
+#define SC_IS_DATA(sc) ((sc) == scData \
+                  || (sc) == scSData \
+                  || (sc) == scRData \
+                  || (sc) == scPData \
+                  || (sc) == scXData)
+#define SC_IS_COMMON(sc) ((sc) == scCommon || (sc) == scSCommon)
+#define SC_IS_BSS(sc) ((sc) == scBss)
+#define SC_IS_SBSS(sc) ((sc) == scSBss)
+#define SC_IS_UNDEF(sc) ((sc) == scUndefined || (sc) == scSUndefined)
+\f
+/* Various complaints about symbol reading that don't abort the process */
+
+static struct complaint bad_file_number_complaint =
+{"bad file number %d", 0, 0};
+
+static struct complaint index_complaint =
+{"bad aux index at symbol %s", 0, 0};
+
+static struct complaint aux_index_complaint =
+{"bad proc end in aux found from symbol %s", 0, 0};
+
+static struct complaint block_index_complaint =
+{"bad aux index at block symbol %s", 0, 0};
+
+static struct complaint unknown_ext_complaint =
+{"unknown external symbol %s", 0, 0};
+
+static struct complaint unknown_sym_complaint =
+{"unknown local symbol %s", 0, 0};
+
+static struct complaint unknown_st_complaint =
+{"with type %d", 0, 0};
+
+static struct complaint block_overflow_complaint =
+{"block containing %s overfilled", 0, 0};
+
+static struct complaint basic_type_complaint =
+{"cannot map ECOFF basic type 0x%x for %s", 0, 0};
+
+static struct complaint unknown_type_qual_complaint =
+{"unknown type qualifier 0x%x", 0, 0};
+
+static struct complaint array_index_type_complaint =
+{"illegal array index type for %s, assuming int", 0, 0};
+
+static struct complaint bad_tag_guess_complaint =
+{"guessed tag type of %s incorrectly", 0, 0};
+
+static struct complaint block_member_complaint =
+{"declaration block contains unhandled symbol type %d", 0, 0};
+
+static struct complaint stEnd_complaint =
+{"stEnd with storage class %d not handled", 0, 0};
+
+static struct complaint unknown_mdebug_symtype_complaint =
+{"unknown symbol type 0x%x", 0, 0};
+
+static struct complaint stab_unknown_complaint =
+{"unknown stabs symbol %s", 0, 0};
+
+static struct complaint pdr_for_nonsymbol_complaint =
+{"PDR for %s, but no symbol", 0, 0};
+
+static struct complaint pdr_static_symbol_complaint =
+{"can't handle PDR for static proc at 0x%lx", 0, 0};
+
+static struct complaint bad_setjmp_pdr_complaint =
+{"fixing bad setjmp PDR from libc", 0, 0};
+
+static struct complaint bad_fbitfield_complaint =
+{"can't handle TIR fBitfield for %s", 0, 0};
+
+static struct complaint bad_continued_complaint =
+{"illegal TIR continued for %s", 0, 0};
+
+static struct complaint bad_rfd_entry_complaint =
+{"bad rfd entry for %s: file %d, index %d", 0, 0};
+
+static struct complaint unexpected_type_code_complaint =
+{"unexpected type code for %s", 0, 0};
+
+static struct complaint unable_to_cross_ref_complaint =
+{"unable to cross ref btTypedef for %s", 0, 0};
+
+static struct complaint bad_indirect_xref_complaint =
+{"unable to cross ref btIndirect for %s", 0, 0};
+
+static struct complaint illegal_forward_tq0_complaint =
+{"illegal tq0 in forward typedef for %s", 0, 0};
+
+static struct complaint illegal_forward_bt_complaint =
+{"illegal bt %d in forward typedef for %s", 0, 0};
+
+static struct complaint bad_linetable_guess_complaint =
+{"guessed size of linetable for %s incorrectly", 0, 0};
+
+static struct complaint bad_ext_ifd_complaint =
+{"bad ifd for external symbol: %d (max %d)", 0, 0};
+
+static struct complaint bad_ext_iss_complaint =
+{"bad iss for external symbol: %ld (max %ld)", 0, 0};
+
+/* Macros and extra defs */
+
+/* Puns: hard to find whether -g was used and how */
+
+#define MIN_GLEVEL GLEVEL_0
+#define compare_glevel(a,b)                                    \
+       (((a) == GLEVEL_3) ? ((b) < GLEVEL_3) :                 \
+        ((b) == GLEVEL_3) ? -1 : (int)((b) - (a)))
+\f
+/* Things that really are local to this module */
+
+/* Remember what we deduced to be the source language of this psymtab. */
+
+static enum language psymtab_language = language_unknown;
+
+/* Current BFD.  */
+
+static bfd *cur_bfd;
+
+/* How to parse debugging information for CUR_BFD.  */
+
+static const struct ecoff_debug_swap *debug_swap;
+
+/* Pointers to debugging information for CUR_BFD.  */
+
+static struct ecoff_debug_info *debug_info;
+
+/* Pointer to current file decriptor record, and its index */
+
+static FDR *cur_fdr;
+static int cur_fd;
+
+/* Index of current symbol */
+
+static int cur_sdx;
+
+/* Note how much "debuggable" this image is.  We would like
+   to see at least one FDR with full symbols */
+
+static int max_gdbinfo;
+static int max_glevel;
+
+/* When examining .o files, report on undefined symbols */
+
+static int n_undef_symbols, n_undef_labels, n_undef_vars, n_undef_procs;
+
+/* Pseudo symbol to use when putting stabs into the symbol table.  */
+
+static char stabs_symbol[] = STABS_SYMBOL;
+
+/* Types corresponding to mdebug format bt* basic types.  */
+
+static struct type *mdebug_type_void;
+static struct type *mdebug_type_char;
+static struct type *mdebug_type_short;
+static struct type *mdebug_type_int_32;
+#define mdebug_type_int mdebug_type_int_32
+static struct type *mdebug_type_int_64;
+static struct type *mdebug_type_long_32;
+static struct type *mdebug_type_long_64;
+static struct type *mdebug_type_long_long_64;
+static struct type *mdebug_type_unsigned_char;
+static struct type *mdebug_type_unsigned_short;
+static struct type *mdebug_type_unsigned_int_32;
+static struct type *mdebug_type_unsigned_int_64;
+static struct type *mdebug_type_unsigned_long_32;
+static struct type *mdebug_type_unsigned_long_64;
+static struct type *mdebug_type_unsigned_long_long_64;
+static struct type *mdebug_type_adr_32;
+static struct type *mdebug_type_adr_64;
+static struct type *mdebug_type_float;
+static struct type *mdebug_type_double;
+static struct type *mdebug_type_complex;
+static struct type *mdebug_type_double_complex;
+static struct type *mdebug_type_fixed_dec;
+static struct type *mdebug_type_float_dec;
+static struct type *mdebug_type_string;
+
+/* Types for symbols from files compiled without debugging info.  */
+
+static struct type *nodebug_func_symbol_type;
+static struct type *nodebug_var_symbol_type;
+
+/* Nonzero if we have seen ecoff debugging info for a file.  */
+
+static int found_ecoff_debugging_info;
+
+/* Forward declarations */
+
+static int upgrade_type (int, struct type **, int, union aux_ext *,
+                        int, char *);
+
+static void parse_partial_symbols (struct objfile *);
+
+static int has_opaque_xref (FDR *, SYMR *);
+
+static int cross_ref (int, union aux_ext *, struct type **, enum type_code,
+                     char **, int, char *);
+
+static struct symbol *new_symbol (char *);
+
+static struct type *new_type (char *);
+
+static struct block *new_block (int);
+
+static struct symtab *new_symtab (char *, int, int, struct objfile *);
+
+static struct linetable *new_linetable (int);
+
+static struct blockvector *new_bvect (int);
+
+static struct type *parse_type (int, union aux_ext *, unsigned int, int *,
+                               int, char *);
+
+static struct symbol *mylookup_symbol (char *, struct block *, namespace_enum,
+                                      enum address_class);
+
+static struct block *shrink_block (struct block *, struct symtab *);
+
+static void sort_blocks (struct symtab *);
+
+static struct partial_symtab *new_psymtab (char *, struct objfile *);
+
+static void psymtab_to_symtab_1 (struct partial_symtab *, char *);
+
+static void add_block (struct block *, struct symtab *);
+
+static void add_symbol (struct symbol *, struct block *);
+
+static int add_line (struct linetable *, int, CORE_ADDR, int);
+
+static struct linetable *shrink_linetable (struct linetable *);
+
+static void handle_psymbol_enumerators (struct objfile *, FDR *, int,
+                                       CORE_ADDR);
+
+static char *mdebug_next_symbol_text (struct objfile *);
+\f
+/* Address bounds for the signal trampoline in inferior, if any */
+
+CORE_ADDR sigtramp_address, sigtramp_end;
+
+/* Allocate zeroed memory */
+
+static void *
+xzalloc (unsigned int size)
+{
+  void *p = xmalloc (size);
+
+  memset (p, 0, size);
+  return p;
+}
+
+/* Exported procedure: Builds a symtab from the PST partial one.
+   Restores the environment in effect when PST was created, delegates
+   most of the work to an ancillary procedure, and sorts
+   and reorders the symtab list at the end */
+
+static void
+mdebug_psymtab_to_symtab (struct partial_symtab *pst)
+{
+
+  if (!pst)
+    return;
+
+  if (info_verbose)
+    {
+      printf_filtered ("Reading in symbols for %s...", pst->filename);
+      gdb_flush (gdb_stdout);
+    }
+
+  next_symbol_text_func = mdebug_next_symbol_text;
+
+  psymtab_to_symtab_1 (pst, pst->filename);
+
+  /* Match with global symbols.  This only needs to be done once,
+     after all of the symtabs and dependencies have been read in.   */
+  scan_file_globals (pst->objfile);
+
+  if (info_verbose)
+    printf_filtered ("done.\n");
+}
+\f
+/* File-level interface functions */
+
+/* Find a file descriptor given its index RF relative to a file CF */
+
+static FDR *
+get_rfd (int cf, int rf)
+{
+  FDR *fdrs;
+  register FDR *f;
+  RFDT rfd;
+
+  fdrs = debug_info->fdr;
+  f = fdrs + cf;
+  /* Object files do not have the RFD table, all refs are absolute */
+  if (f->rfdBase == 0)
+    return fdrs + rf;
+  (*debug_swap->swap_rfd_in) (cur_bfd,
+                             ((char *) debug_info->external_rfd
+                              + ((f->rfdBase + rf)
+                                 * debug_swap->external_rfd_size)),
+                             &rfd);
+  return fdrs + rfd;
+}
+
+/* Return a safer print NAME for a file descriptor */
+
+static char *
+fdr_name (FDR *f)
+{
+  if (f->rss == -1)
+    return "<stripped file>";
+  if (f->rss == 0)
+    return "<NFY>";
+  return debug_info->ss + f->issBase + f->rss;
+}
+
+
+/* Read in and parse the symtab of the file OBJFILE.  Symbols from
+   different sections are relocated via the SECTION_OFFSETS.  */
+
+void
+mdebug_build_psymtabs (struct objfile *objfile,
+                      const struct ecoff_debug_swap *swap,
+                      struct ecoff_debug_info *info)
+{
+  cur_bfd = objfile->obfd;
+  debug_swap = swap;
+  debug_info = info;
+
+  stabsread_new_init ();
+  buildsym_new_init ();
+  free_header_files ();
+  init_header_files ();
+        
+  /* Make sure all the FDR information is swapped in.  */
+  if (info->fdr == (FDR *) NULL)
+    {
+      char *fdr_src;
+      char *fdr_end;
+      FDR *fdr_ptr;
+
+      info->fdr = (FDR *) obstack_alloc (&objfile->psymbol_obstack,
+                                        (info->symbolic_header.ifdMax
+                                         * sizeof (FDR)));
+      fdr_src = info->external_fdr;
+      fdr_end = (fdr_src
+                + info->symbolic_header.ifdMax * swap->external_fdr_size);
+      fdr_ptr = info->fdr;
+      for (; fdr_src < fdr_end; fdr_src += swap->external_fdr_size, fdr_ptr++)
+       (*swap->swap_fdr_in) (objfile->obfd, fdr_src, fdr_ptr);
+    }
+
+  parse_partial_symbols (objfile);
+
+#if 0
+  /* Check to make sure file was compiled with -g.  If not, warn the
+     user of this limitation.  */
+  if (compare_glevel (max_glevel, GLEVEL_2) < 0)
+    {
+      if (max_gdbinfo == 0)
+       printf_unfiltered ("\n%s not compiled with -g, debugging support is limited.\n",
+                          objfile->name);
+      printf_unfiltered ("You should compile with -g2 or -g3 for best debugging support.\n");
+      gdb_flush (gdb_stdout);
+    }
+#endif
+}
+\f
+/* Local utilities */
+
+/* Map of FDR indexes to partial symtabs */
+
+struct pst_map
+{
+  struct partial_symtab *pst;  /* the psymtab proper */
+  long n_globals;              /* exported globals (external symbols) */
+  long globals_offset;         /* cumulative */
+};
+
+
+/* Utility stack, used to nest procedures and blocks properly.
+   It is a doubly linked list, to avoid too many alloc/free.
+   Since we might need it quite a few times it is NOT deallocated
+   after use. */
+
+static struct parse_stack
+  {
+    struct parse_stack *next, *prev;
+    struct symtab *cur_st;     /* Current symtab. */
+    struct block *cur_block;   /* Block in it. */
+
+    /* What are we parsing.  stFile, or stBlock are for files and
+       blocks.  stProc or stStaticProc means we have seen the start of a
+       procedure, but not the start of the block within in.  When we see
+       the start of that block, we change it to stNil, without pushing a
+       new block, i.e. stNil means both a procedure and a block.  */
+
+    int blocktype;
+
+    int maxsyms;               /* Max symbols in this block. */
+    struct type *cur_type;     /* Type we parse fields for. */
+    int cur_field;             /* Field number in cur_type. */
+    CORE_ADDR procadr;         /* Start addres of this procedure */
+    int numargs;               /* Its argument count */
+  }
+
+ *top_stack;                   /* Top stack ptr */
+
+
+/* Enter a new lexical context */
+
+static void
+push_parse_stack (void)
+{
+  struct parse_stack *new;
+
+  /* Reuse frames if possible */
+  if (top_stack && top_stack->prev)
+    new = top_stack->prev;
+  else
+    new = (struct parse_stack *) xzalloc (sizeof (struct parse_stack));
+  /* Initialize new frame with previous content */
+  if (top_stack)
+    {
+      register struct parse_stack *prev = new->prev;
+
+      *new = *top_stack;
+      top_stack->prev = new;
+      new->prev = prev;
+      new->next = top_stack;
+    }
+  top_stack = new;
+}
+
+/* Exit a lexical context */
+
+static void
+pop_parse_stack (void)
+{
+  if (!top_stack)
+    return;
+  if (top_stack->next)
+    top_stack = top_stack->next;
+}
+
+
+/* Cross-references might be to things we haven't looked at
+   yet, e.g. type references.  To avoid too many type
+   duplications we keep a quick fixup table, an array
+   of lists of references indexed by file descriptor */
+
+struct mdebug_pending
+{
+  struct mdebug_pending *next; /* link */
+  char *s;                     /* the unswapped symbol */
+  struct type *t;              /* its partial type descriptor */
+};
+
+
+/* The pending information is kept for an entire object file, and used
+   to be in the sym_private field.  I took it out when I split
+   mdebugread from mipsread, because this might not be the only type
+   of symbols read from an object file.  Instead, we allocate the
+   pending information table when we create the partial symbols, and
+   we store a pointer to the single table in each psymtab.  */
+
+static struct mdebug_pending **pending_list;
+
+/* Check whether we already saw symbol SH in file FH */
+
+static struct mdebug_pending *
+is_pending_symbol (FDR *fh, char *sh)
+{
+  int f_idx = fh - debug_info->fdr;
+  register struct mdebug_pending *p;
+
+  /* Linear search is ok, list is typically no more than 10 deep */
+  for (p = pending_list[f_idx]; p; p = p->next)
+    if (p->s == sh)
+      break;
+  return p;
+}
+
+/* Add a new symbol SH of type T */
+
+static void
+add_pending (FDR *fh, char *sh, struct type *t)
+{
+  int f_idx = fh - debug_info->fdr;
+  struct mdebug_pending *p = is_pending_symbol (fh, sh);
+
+  /* Make sure we do not make duplicates */
+  if (!p)
+    {
+      p = ((struct mdebug_pending *)
+          obstack_alloc (&current_objfile->psymbol_obstack,
+                         sizeof (struct mdebug_pending)));
+      p->s = sh;
+      p->t = t;
+      p->next = pending_list[f_idx];
+      pending_list[f_idx] = p;
+    }
+}
+\f
+
+/* Parsing Routines proper. */
+
+/* Parse a single symbol. Mostly just make up a GDB symbol for it.
+   For blocks, procedures and types we open a new lexical context.
+   This is basically just a big switch on the symbol's type.  Argument
+   AX is the base pointer of aux symbols for this file (fh->iauxBase).
+   EXT_SH points to the unswapped symbol, which is needed for struct,
+   union, etc., types; it is NULL for an EXTR.  BIGEND says whether
+   aux symbols are big-endian or little-endian.  Return count of
+   SYMR's handled (normally one).  */
+
+static int
+parse_symbol (SYMR *sh, union aux_ext *ax, char *ext_sh, int bigend,
+             struct section_offsets *section_offsets, struct objfile *objfile)
+{
+  const bfd_size_type external_sym_size = debug_swap->external_sym_size;
+  void (*const swap_sym_in) (bfd *, void *, SYMR *) = debug_swap->swap_sym_in;
+  char *name;
+  struct symbol *s;
+  struct block *b;
+  struct mdebug_pending *pend;
+  struct type *t;
+  struct field *f;
+  int count = 1;
+  enum address_class class;
+  TIR tir;
+  long svalue = sh->value;
+  int bitsize;
+
+  if (ext_sh == (char *) NULL)
+    name = debug_info->ssext + sh->iss;
+  else
+    name = debug_info->ss + cur_fdr->issBase + sh->iss;
+
+  switch (sh->sc)
+    {
+    case scText:
+    case scRConst:
+      /* Do not relocate relative values.
+         The value of a stEnd symbol is the displacement from the
+         corresponding start symbol value.
+         The value of a stBlock symbol is the displacement from the
+         procedure address.  */
+      if (sh->st != stEnd && sh->st != stBlock)
+       sh->value += ANOFFSET (section_offsets, SECT_OFF_TEXT (objfile));
+      break;
+    case scData:
+    case scSData:
+    case scRData:
+    case scPData:
+    case scXData:
+      sh->value += ANOFFSET (section_offsets, SECT_OFF_DATA (objfile));
+      break;
+    case scBss:
+    case scSBss:
+      sh->value += ANOFFSET (section_offsets, SECT_OFF_BSS (objfile));
+      break;
+    }
+
+  switch (sh->st)
+    {
+    case stNil:
+      break;
+
+    case stGlobal:             /* external symbol, goes into global block */
+      class = LOC_STATIC;
+      b = BLOCKVECTOR_BLOCK (BLOCKVECTOR (top_stack->cur_st),
+                            GLOBAL_BLOCK);
+      s = new_symbol (name);
+      SYMBOL_VALUE_ADDRESS (s) = (CORE_ADDR) sh->value;
+      goto data;
+
+    case stStatic:             /* static data, goes into current block. */
+      class = LOC_STATIC;
+      b = top_stack->cur_block;
+      s = new_symbol (name);
+      if (SC_IS_COMMON (sh->sc))
+       {
+         /* It is a FORTRAN common block.  At least for SGI Fortran the
+            address is not in the symbol; we need to fix it later in
+            scan_file_globals.  */
+         int bucket = hashname (SYMBOL_NAME (s));
+         SYMBOL_VALUE_CHAIN (s) = global_sym_chain[bucket];
+         global_sym_chain[bucket] = s;
+       }
+      else
+       SYMBOL_VALUE_ADDRESS (s) = (CORE_ADDR) sh->value;
+      goto data;
+
+    case stLocal:              /* local variable, goes into current block */
+      if (sh->sc == scRegister)
+       {
+         class = LOC_REGISTER;
+         svalue = ECOFF_REG_TO_REGNUM (svalue);
+       }
+      else
+       class = LOC_LOCAL;
+      b = top_stack->cur_block;
+      s = new_symbol (name);
+      SYMBOL_VALUE (s) = svalue;
+
+    data:                      /* Common code for symbols describing data */
+      SYMBOL_NAMESPACE (s) = VAR_NAMESPACE;
+      SYMBOL_CLASS (s) = class;
+      add_symbol (s, b);
+
+      /* Type could be missing if file is compiled without debugging info.  */
+      if (SC_IS_UNDEF (sh->sc)
+         || sh->sc == scNil || sh->index == indexNil)
+       SYMBOL_TYPE (s) = nodebug_var_symbol_type;
+      else
+       SYMBOL_TYPE (s) = parse_type (cur_fd, ax, sh->index, 0, bigend, name);
+      /* Value of a data symbol is its memory address */
+      break;
+
+    case stParam:              /* arg to procedure, goes into current block */
+      max_gdbinfo++;
+      found_ecoff_debugging_info = 1;
+      top_stack->numargs++;
+
+      /* Special GNU C++ name.  */
+      if (is_cplus_marker (name[0]) && name[1] == 't' && name[2] == 0)
+       name = "this";          /* FIXME, not alloc'd in obstack */
+      s = new_symbol (name);
+
+      SYMBOL_NAMESPACE (s) = VAR_NAMESPACE;
+      switch (sh->sc)
+       {
+       case scRegister:
+         /* Pass by value in register.  */
+         SYMBOL_CLASS (s) = LOC_REGPARM;
+         svalue = ECOFF_REG_TO_REGNUM (svalue);
+         break;
+       case scVar:
+         /* Pass by reference on stack.  */
+         SYMBOL_CLASS (s) = LOC_REF_ARG;
+         break;
+       case scVarRegister:
+         /* Pass by reference in register.  */
+         SYMBOL_CLASS (s) = LOC_REGPARM_ADDR;
+         svalue = ECOFF_REG_TO_REGNUM (svalue);
+         break;
+       default:
+         /* Pass by value on stack.  */
+         SYMBOL_CLASS (s) = LOC_ARG;
+         break;
+       }
+      SYMBOL_VALUE (s) = svalue;
+      SYMBOL_TYPE (s) = parse_type (cur_fd, ax, sh->index, 0, bigend, name);
+      add_symbol (s, top_stack->cur_block);
+      break;
+
+    case stLabel:              /* label, goes into current block */
+      s = new_symbol (name);
+      SYMBOL_NAMESPACE (s) = VAR_NAMESPACE;    /* so that it can be used */
+      SYMBOL_CLASS (s) = LOC_LABEL;    /* but not misused */
+      SYMBOL_VALUE_ADDRESS (s) = (CORE_ADDR) sh->value;
+      SYMBOL_TYPE (s) = mdebug_type_int;
+      add_symbol (s, top_stack->cur_block);
+      break;
+
+    case stProc:               /* Procedure, usually goes into global block */
+    case stStaticProc:         /* Static procedure, goes into current block */
+      s = new_symbol (name);
+      SYMBOL_NAMESPACE (s) = VAR_NAMESPACE;
+      SYMBOL_CLASS (s) = LOC_BLOCK;
+      /* Type of the return value */
+      if (SC_IS_UNDEF (sh->sc) || sh->sc == scNil)
+       t = mdebug_type_int;
+      else
+       {
+         t = parse_type (cur_fd, ax, sh->index + 1, 0, bigend, name);
+         if (STREQ (name, "malloc") && TYPE_CODE (t) == TYPE_CODE_VOID)
+           {
+             /* I don't know why, but, at least under Alpha GNU/Linux,
+                when linking against a malloc without debugging
+                symbols, its read as a function returning void---this
+                is bad because it means we cannot call functions with
+                string arguments interactively; i.e., "call
+                printf("howdy\n")" would fail with the error message
+                "program has no memory available".  To avoid this, we
+                patch up the type and make it void*
+                instead. (davidm@azstarnet.com)
+              */
+             t = make_pointer_type (t, NULL);
+           }
+       }
+      b = top_stack->cur_block;
+      if (sh->st == stProc)
+       {
+         struct blockvector *bv = BLOCKVECTOR (top_stack->cur_st);
+         /* The next test should normally be true, but provides a
+            hook for nested functions (which we don't want to make
+            global). */
+         if (b == BLOCKVECTOR_BLOCK (bv, STATIC_BLOCK))
+           b = BLOCKVECTOR_BLOCK (bv, GLOBAL_BLOCK);
+         /* Irix 5 sometimes has duplicate names for the same
+            function.  We want to add such names up at the global
+            level, not as a nested function.  */
+         else if (sh->value == top_stack->procadr)
+           b = BLOCKVECTOR_BLOCK (bv, GLOBAL_BLOCK);
+       }
+      add_symbol (s, b);
+
+      /* Make a type for the procedure itself */
+      SYMBOL_TYPE (s) = lookup_function_type (t);
+
+      /* Create and enter a new lexical context */
+      b = new_block (top_stack->maxsyms);
+      SYMBOL_BLOCK_VALUE (s) = b;
+      BLOCK_FUNCTION (b) = s;
+      BLOCK_START (b) = BLOCK_END (b) = sh->value;
+      BLOCK_SUPERBLOCK (b) = top_stack->cur_block;
+      add_block (b, top_stack->cur_st);
+
+      /* Not if we only have partial info */
+      if (SC_IS_UNDEF (sh->sc) || sh->sc == scNil)
+       break;
+
+      push_parse_stack ();
+      top_stack->cur_block = b;
+      top_stack->blocktype = sh->st;
+      top_stack->cur_type = SYMBOL_TYPE (s);
+      top_stack->cur_field = -1;
+      top_stack->procadr = sh->value;
+      top_stack->numargs = 0;
+      break;
+
+      /* Beginning of code for structure, union, and enum definitions.
+         They all share a common set of local variables, defined here.  */
+      {
+       enum type_code type_code;
+       char *ext_tsym;
+       int nfields;
+       long max_value;
+       struct field *f;
+
+    case stStruct:             /* Start a block defining a struct type */
+       type_code = TYPE_CODE_STRUCT;
+       goto structured_common;
+
+    case stUnion:              /* Start a block defining a union type */
+       type_code = TYPE_CODE_UNION;
+       goto structured_common;
+
+    case stEnum:               /* Start a block defining an enum type */
+       type_code = TYPE_CODE_ENUM;
+       goto structured_common;
+
+    case stBlock:              /* Either a lexical block, or some type */
+       if (sh->sc != scInfo && !SC_IS_COMMON (sh->sc))
+         goto case_stBlock_code;       /* Lexical block */
+
+       type_code = TYPE_CODE_UNDEF;    /* We have a type.  */
+
+       /* Common code for handling struct, union, enum, and/or as-yet-
+          unknown-type blocks of info about structured data.  `type_code'
+          has been set to the proper TYPE_CODE, if we know it.  */
+      structured_common:
+       found_ecoff_debugging_info = 1;
+       push_parse_stack ();
+       top_stack->blocktype = stBlock;
+
+       /* First count the number of fields and the highest value. */
+       nfields = 0;
+       max_value = 0;
+       for (ext_tsym = ext_sh + external_sym_size;
+            ;
+            ext_tsym += external_sym_size)
+         {
+           SYMR tsym;
+
+           (*swap_sym_in) (cur_bfd, ext_tsym, &tsym);
+
+           switch (tsym.st)
+             {
+             case stEnd:
+               goto end_of_fields;
+
+             case stMember:
+               if (nfields == 0 && type_code == TYPE_CODE_UNDEF)
+                 {
+                   /* If the type of the member is Nil (or Void),
+                      without qualifiers, assume the tag is an
+                      enumeration.
+                      Alpha cc -migrate enums are recognized by a zero
+                      index and a zero symbol value.
+                      DU 4.0 cc enums are recognized by a member type of
+                      btEnum without qualifiers and a zero symbol value.  */
+                   if (tsym.index == indexNil
+                       || (tsym.index == 0 && sh->value == 0))
+                     type_code = TYPE_CODE_ENUM;
+                   else
+                     {
+                       (*debug_swap->swap_tir_in) (bigend,
+                                                   &ax[tsym.index].a_ti,
+                                                   &tir);
+                       if ((tir.bt == btNil || tir.bt == btVoid
+                            || (tir.bt == btEnum && sh->value == 0))
+                           && tir.tq0 == tqNil)
+                         type_code = TYPE_CODE_ENUM;
+                     }
+                 }
+               nfields++;
+               if (tsym.value > max_value)
+                 max_value = tsym.value;
+               break;
+
+             case stBlock:
+             case stUnion:
+             case stEnum:
+             case stStruct:
+               {
+#if 0
+                 /* This is a no-op; is it trying to tell us something
+                    we should be checking?  */
+                 if (tsym.sc == scVariant);    /*UNIMPLEMENTED */
+#endif
+                 if (tsym.index != 0)
+                   {
+                     /* This is something like a struct within a
+                        struct.  Skip over the fields of the inner
+                        struct.  The -1 is because the for loop will
+                        increment ext_tsym.  */
+                     ext_tsym = ((char *) debug_info->external_sym
+                                 + ((cur_fdr->isymBase + tsym.index - 1)
+                                    * external_sym_size));
+                   }
+               }
+               break;
+
+             case stTypedef:
+               /* mips cc puts out a typedef for struct x if it is not yet
+                  defined when it encounters
+                  struct y { struct x *xp; };
+                  Just ignore it. */
+               break;
+
+             case stIndirect:
+               /* Irix5 cc puts out a stIndirect for struct x if it is not
+                  yet defined when it encounters
+                  struct y { struct x *xp; };
+                  Just ignore it. */
+               break;
+
+             default:
+               complain (&block_member_complaint, tsym.st);
+             }
+         }
+      end_of_fields:;
+
+       /* In an stBlock, there is no way to distinguish structs,
+          unions, and enums at this point.  This is a bug in the
+          original design (that has been fixed with the recent
+          addition of the stStruct, stUnion, and stEnum symbol
+          types.)  The way you can tell is if/when you see a variable
+          or field of that type.  In that case the variable's type
+          (in the AUX table) says if the type is struct, union, or
+          enum, and points back to the stBlock here.  So you can
+          patch the tag kind up later - but only if there actually is
+          a variable or field of that type.
+
+          So until we know for sure, we will guess at this point.
+          The heuristic is:
+          If the first member has index==indexNil or a void type,
+          assume we have an enumeration.
+          Otherwise, if there is more than one member, and all
+          the members have offset 0, assume we have a union.
+          Otherwise, assume we have a struct.
+
+          The heuristic could guess wrong in the case of of an
+          enumeration with no members or a union with one (or zero)
+          members, or when all except the last field of a struct have
+          width zero.  These are uncommon and/or illegal situations,
+          and in any case guessing wrong probably doesn't matter
+          much.
+
+          But if we later do find out we were wrong, we fixup the tag
+          kind.  Members of an enumeration must be handled
+          differently from struct/union fields, and that is harder to
+          patch up, but luckily we shouldn't need to.  (If there are
+          any enumeration members, we can tell for sure it's an enum
+          here.) */
+
+       if (type_code == TYPE_CODE_UNDEF)
+         {
+           if (nfields > 1 && max_value == 0)
+             type_code = TYPE_CODE_UNION;
+           else
+             type_code = TYPE_CODE_STRUCT;
+         }
+
+       /* Create a new type or use the pending type.  */
+       pend = is_pending_symbol (cur_fdr, ext_sh);
+       if (pend == (struct mdebug_pending *) NULL)
+         {
+           t = new_type (NULL);
+           add_pending (cur_fdr, ext_sh, t);
+         }
+       else
+         t = pend->t;
+
+       /* Do not set the tag name if it is a compiler generated tag name
+          (.Fxx or .xxfake or empty) for unnamed struct/union/enums.
+          Alpha cc puts out an sh->iss of zero for those.  */
+       if (sh->iss == 0 || name[0] == '.' || name[0] == '\0')
+         TYPE_TAG_NAME (t) = NULL;
+       else
+         TYPE_TAG_NAME (t) = obconcat (&current_objfile->symbol_obstack,
+                                       "", "", name);
+
+       TYPE_CODE (t) = type_code;
+       TYPE_LENGTH (t) = sh->value;
+       TYPE_NFIELDS (t) = nfields;
+       TYPE_FIELDS (t) = f = ((struct field *)
+                              TYPE_ALLOC (t,
+                                          nfields * sizeof (struct field)));
+
+       if (type_code == TYPE_CODE_ENUM)
+         {
+           int unsigned_enum = 1;
+
+           /* This is a non-empty enum. */
+
+           /* DEC c89 has the number of enumerators in the sh.value field,
+              not the type length, so we have to compensate for that
+              incompatibility quirk.
+              This might do the wrong thing for an enum with one or two
+              enumerators and gcc -gcoff -fshort-enums, but these cases
+              are hopefully rare enough.
+              Alpha cc -migrate has a sh.value field of zero, we adjust
+              that too.  */
+           if (TYPE_LENGTH (t) == TYPE_NFIELDS (t)
+               || TYPE_LENGTH (t) == 0)
+             TYPE_LENGTH (t) = TARGET_INT_BIT / HOST_CHAR_BIT;
+           for (ext_tsym = ext_sh + external_sym_size;
+                ;
+                ext_tsym += external_sym_size)
+             {
+               SYMR tsym;
+               struct symbol *enum_sym;
+
+               (*swap_sym_in) (cur_bfd, ext_tsym, &tsym);
+
+               if (tsym.st != stMember)
+                 break;
+
+               FIELD_BITPOS (*f) = tsym.value;
+               FIELD_TYPE (*f) = t;
+               FIELD_NAME (*f) = debug_info->ss + cur_fdr->issBase + tsym.iss;
+               FIELD_BITSIZE (*f) = 0;
+
+               enum_sym = ((struct symbol *)
+                           obstack_alloc (&current_objfile->symbol_obstack,
+                                          sizeof (struct symbol)));
+               memset (enum_sym, 0, sizeof (struct symbol));
+               SYMBOL_NAME (enum_sym) =
+                 obsavestring (f->name, strlen (f->name),
+                               &current_objfile->symbol_obstack);
+               SYMBOL_CLASS (enum_sym) = LOC_CONST;
+               SYMBOL_TYPE (enum_sym) = t;
+               SYMBOL_NAMESPACE (enum_sym) = VAR_NAMESPACE;
+               SYMBOL_VALUE (enum_sym) = tsym.value;
+               if (SYMBOL_VALUE (enum_sym) < 0)
+                 unsigned_enum = 0;
+               add_symbol (enum_sym, top_stack->cur_block);
+
+               /* Skip the stMembers that we've handled. */
+               count++;
+               f++;
+             }
+           if (unsigned_enum)
+             TYPE_FLAGS (t) |= TYPE_FLAG_UNSIGNED;
+         }
+       /* make this the current type */
+       top_stack->cur_type = t;
+       top_stack->cur_field = 0;
+
+       /* Do not create a symbol for alpha cc unnamed structs.  */
+       if (sh->iss == 0)
+         break;
+
+       /* gcc puts out an empty struct for an opaque struct definitions,
+          do not create a symbol for it either.  */
+       if (TYPE_NFIELDS (t) == 0)
+         {
+           TYPE_FLAGS (t) |= TYPE_FLAG_STUB;
+           break;
+         }
+
+       s = new_symbol (name);
+       SYMBOL_NAMESPACE (s) = STRUCT_NAMESPACE;
+       SYMBOL_CLASS (s) = LOC_TYPEDEF;
+       SYMBOL_VALUE (s) = 0;
+       SYMBOL_TYPE (s) = t;
+       add_symbol (s, top_stack->cur_block);
+       break;
+
+       /* End of local variables shared by struct, union, enum, and
+          block (as yet unknown struct/union/enum) processing.  */
+      }
+
+    case_stBlock_code:
+      found_ecoff_debugging_info = 1;
+      /* beginnning of (code) block. Value of symbol
+         is the displacement from procedure start */
+      push_parse_stack ();
+
+      /* Do not start a new block if this is the outermost block of a
+         procedure.  This allows the LOC_BLOCK symbol to point to the
+         block with the local variables, so funcname::var works.  */
+      if (top_stack->blocktype == stProc
+         || top_stack->blocktype == stStaticProc)
+       {
+         top_stack->blocktype = stNil;
+         break;
+       }
+
+      top_stack->blocktype = stBlock;
+      b = new_block (top_stack->maxsyms);
+      BLOCK_START (b) = sh->value + top_stack->procadr;
+      BLOCK_SUPERBLOCK (b) = top_stack->cur_block;
+      top_stack->cur_block = b;
+      add_block (b, top_stack->cur_st);
+      break;
+
+    case stEnd:                /* end (of anything) */
+      if (sh->sc == scInfo || SC_IS_COMMON (sh->sc))
+       {
+         /* Finished with type */
+         top_stack->cur_type = 0;
+       }
+      else if (sh->sc == scText &&
+              (top_stack->blocktype == stProc ||
+               top_stack->blocktype == stStaticProc))
+       {
+         /* Finished with procedure */
+         struct blockvector *bv = BLOCKVECTOR (top_stack->cur_st);
+         struct mips_extra_func_info *e;
+         struct block *b;
+         struct type *ftype = top_stack->cur_type;
+         int i;
+
+         BLOCK_END (top_stack->cur_block) += sh->value;        /* size */
+
+         /* Make up special symbol to contain procedure specific info */
+         s = new_symbol (MIPS_EFI_SYMBOL_NAME);
+         SYMBOL_NAMESPACE (s) = LABEL_NAMESPACE;
+         SYMBOL_CLASS (s) = LOC_CONST;
+         SYMBOL_TYPE (s) = mdebug_type_void;
+         e = ((struct mips_extra_func_info *)
+              obstack_alloc (&current_objfile->symbol_obstack,
+                             sizeof (struct mips_extra_func_info)));
+         memset (e, 0, sizeof (struct mips_extra_func_info));
+         SYMBOL_VALUE (s) = (long) e;
+         e->numargs = top_stack->numargs;
+         e->pdr.framereg = -1;
+         add_symbol (s, top_stack->cur_block);
+
+         /* Reallocate symbols, saving memory */
+         b = shrink_block (top_stack->cur_block, top_stack->cur_st);
+
+         /* f77 emits proc-level with address bounds==[0,0],
+            So look for such child blocks, and patch them.  */
+         for (i = 0; i < BLOCKVECTOR_NBLOCKS (bv); i++)
+           {
+             struct block *b_bad = BLOCKVECTOR_BLOCK (bv, i);
+             if (BLOCK_SUPERBLOCK (b_bad) == b
+                 && BLOCK_START (b_bad) == top_stack->procadr
+                 && BLOCK_END (b_bad) == top_stack->procadr)
+               {
+                 BLOCK_START (b_bad) = BLOCK_START (b);
+                 BLOCK_END (b_bad) = BLOCK_END (b);
+               }
+           }
+
+         if (TYPE_NFIELDS (ftype) <= 0)
+           {
+             /* No parameter type information is recorded with the function's
+                type.  Set that from the type of the parameter symbols. */
+             int nparams = top_stack->numargs;
+             int iparams;
+             struct symbol *sym;
+
+             if (nparams > 0)
+               {
+                 TYPE_NFIELDS (ftype) = nparams;
+                 TYPE_FIELDS (ftype) = (struct field *)
+                   TYPE_ALLOC (ftype, nparams * sizeof (struct field));
+
+                 for (i = iparams = 0; iparams < nparams; i++)
+                   {
+                     sym = BLOCK_SYM (b, i);
+                     switch (SYMBOL_CLASS (sym))
+                       {
+                       case LOC_ARG:
+                       case LOC_REF_ARG:
+                       case LOC_REGPARM:
+                       case LOC_REGPARM_ADDR:
+                         TYPE_FIELD_TYPE (ftype, iparams) = SYMBOL_TYPE (sym);
+                         TYPE_FIELD_ARTIFICIAL (ftype, iparams) = 0;
+                         iparams++;
+                         break;
+                       default:
+                         break;
+                       }
+                   }
+               }
+           }
+       }
+      else if (sh->sc == scText && top_stack->blocktype == stBlock)
+       {
+         /* End of (code) block. The value of the symbol is the
+            displacement from the procedure`s start address of the
+            end of this block. */
+         BLOCK_END (top_stack->cur_block) = sh->value + top_stack->procadr;
+         shrink_block (top_stack->cur_block, top_stack->cur_st);
+       }
+      else if (sh->sc == scText && top_stack->blocktype == stNil)
+       {
+         /* End of outermost block.  Pop parse stack and ignore.  The
+            following stEnd of stProc will take care of the block.  */
+         ;
+       }
+      else if (sh->sc == scText && top_stack->blocktype == stFile)
+       {
+         /* End of file.  Pop parse stack and ignore.  Higher
+            level code deals with this.  */
+         ;
+       }
+      else
+       complain (&stEnd_complaint, sh->sc);
+
+      pop_parse_stack ();      /* restore previous lexical context */
+      break;
+
+    case stMember:             /* member of struct or union */
+      f = &TYPE_FIELDS (top_stack->cur_type)[top_stack->cur_field++];
+      FIELD_NAME (*f) = name;
+      FIELD_BITPOS (*f) = sh->value;
+      bitsize = 0;
+      FIELD_TYPE (*f) = parse_type (cur_fd, ax, sh->index, &bitsize, bigend, name);
+      FIELD_BITSIZE (*f) = bitsize;
+      break;
+
+    case stIndirect:           /* forward declaration on Irix5 */
+      /* Forward declarations from Irix5 cc are handled by cross_ref,
+         skip them.  */
+      break;
+
+    case stTypedef:            /* type definition */
+      found_ecoff_debugging_info = 1;
+
+      /* Typedefs for forward declarations and opaque structs from alpha cc
+         are handled by cross_ref, skip them.  */
+      if (sh->iss == 0)
+       break;
+
+      /* Parse the type or use the pending type.  */
+      pend = is_pending_symbol (cur_fdr, ext_sh);
+      if (pend == (struct mdebug_pending *) NULL)
+       {
+         t = parse_type (cur_fd, ax, sh->index, (int *) NULL, bigend, name);
+         add_pending (cur_fdr, ext_sh, t);
+       }
+      else
+       t = pend->t;
+
+      /* mips cc puts out a typedef with the name of the struct for forward
+         declarations. These should not go into the symbol table and
+         TYPE_NAME should not be set for them.
+         They can't be distinguished from an intentional typedef to
+         the same name however:
+         x.h:
+         struct x { int ix; int jx; };
+         struct xx;
+         x.c:
+         typedef struct x x;
+         struct xx {int ixx; int jxx; };
+         generates a cross referencing stTypedef for x and xx.
+         The user visible effect of this is that the type of a pointer
+         to struct foo sometimes is given as `foo *' instead of `struct foo *'.
+         The problem is fixed with alpha cc and Irix5 cc.  */
+
+      /* However if the typedef cross references to an opaque aggregate, it
+         is safe to omit it from the symbol table.  */
+
+      if (has_opaque_xref (cur_fdr, sh))
+       break;
+      s = new_symbol (name);
+      SYMBOL_NAMESPACE (s) = VAR_NAMESPACE;
+      SYMBOL_CLASS (s) = LOC_TYPEDEF;
+      SYMBOL_BLOCK_VALUE (s) = top_stack->cur_block;
+      SYMBOL_TYPE (s) = t;
+      add_symbol (s, top_stack->cur_block);
+
+      /* Incomplete definitions of structs should not get a name.  */
+      if (TYPE_NAME (SYMBOL_TYPE (s)) == NULL
+         && (TYPE_NFIELDS (SYMBOL_TYPE (s)) != 0
+             || (TYPE_CODE (SYMBOL_TYPE (s)) != TYPE_CODE_STRUCT
+                 && TYPE_CODE (SYMBOL_TYPE (s)) != TYPE_CODE_UNION)))
+       {
+         if (TYPE_CODE (SYMBOL_TYPE (s)) == TYPE_CODE_PTR
+             || TYPE_CODE (SYMBOL_TYPE (s)) == TYPE_CODE_FUNC)
+           {
+             /* If we are giving a name to a type such as "pointer to
+                foo" or "function returning foo", we better not set
+                the TYPE_NAME.  If the program contains "typedef char
+                *caddr_t;", we don't want all variables of type char
+                * to print as caddr_t.  This is not just a
+                consequence of GDB's type management; CC and GCC (at
+                least through version 2.4) both output variables of
+                either type char * or caddr_t with the type
+                refering to the stTypedef symbol for caddr_t.  If a future
+                compiler cleans this up it GDB is not ready for it
+                yet, but if it becomes ready we somehow need to
+                disable this check (without breaking the PCC/GCC2.4
+                case).
+
+                Sigh.
+
+                Fortunately, this check seems not to be necessary
+                for anything except pointers or functions.  */
+           }
+         else
+           TYPE_NAME (SYMBOL_TYPE (s)) = SYMBOL_NAME (s);
+       }
+      break;
+
+    case stFile:               /* file name */
+      push_parse_stack ();
+      top_stack->blocktype = sh->st;
+      break;
+
+      /* I`ve never seen these for C */
+    case stRegReloc:
+      break;                   /* register relocation */
+    case stForward:
+      break;                   /* forwarding address */
+    case stConstant:
+      break;                   /* constant */
+    default:
+      complain (&unknown_mdebug_symtype_complaint, sh->st);
+      break;
+    }
+
+  return count;
+}
+
+/* Parse the type information provided in the raw AX entries for
+   the symbol SH. Return the bitfield size in BS, in case.
+   We must byte-swap the AX entries before we use them; BIGEND says whether
+   they are big-endian or little-endian (from fh->fBigendian).  */
+
+static struct type *
+parse_type (int fd, union aux_ext *ax, unsigned int aux_index, int *bs,
+           int bigend, char *sym_name)
+{
+  /* Null entries in this map are treated specially */
+  static struct type **map_bt[] =
+  {
+    &mdebug_type_void,         /* btNil */
+    &mdebug_type_adr_32,       /* btAdr */
+    &mdebug_type_char,         /* btChar */
+    &mdebug_type_unsigned_char,        /* btUChar */
+    &mdebug_type_short,                /* btShort */
+    &mdebug_type_unsigned_short,       /* btUShort */
+    &mdebug_type_int_32,       /* btInt */
+    &mdebug_type_unsigned_int_32,      /* btUInt */
+    &mdebug_type_long_32,      /* btLong */
+    &mdebug_type_unsigned_long_32,     /* btULong */
+    &mdebug_type_float,                /* btFloat */
+    &mdebug_type_double,       /* btDouble */
+    0,                         /* btStruct */
+    0,                         /* btUnion */
+    0,                         /* btEnum */
+    0,                         /* btTypedef */
+    0,                         /* btRange */
+    0,                         /* btSet */
+    &mdebug_type_complex,      /* btComplex */
+    &mdebug_type_double_complex,       /* btDComplex */
+    0,                         /* btIndirect */
+    &mdebug_type_fixed_dec,    /* btFixedDec */
+    &mdebug_type_float_dec,    /* btFloatDec */
+    &mdebug_type_string,       /* btString */
+    0,                         /* btBit */
+    0,                         /* btPicture */
+    &mdebug_type_void,         /* btVoid */
+    0,                         /* DEC C++:  Pointer to member */
+    0,                         /* DEC C++:  Virtual function table */
+    0,                         /* DEC C++:  Class (Record) */
+    &mdebug_type_long_64,      /* btLong64  */
+    &mdebug_type_unsigned_long_64,     /* btULong64 */
+    &mdebug_type_long_long_64, /* btLongLong64  */
+    &mdebug_type_unsigned_long_long_64,                /* btULongLong64 */
+    &mdebug_type_adr_64,       /* btAdr64 */
+    &mdebug_type_int_64,       /* btInt64  */
+    &mdebug_type_unsigned_int_64,      /* btUInt64 */
+  };
+
+  TIR t[1];
+  struct type *tp = 0;
+  enum type_code type_code = TYPE_CODE_UNDEF;
+
+  /* Handle undefined types, they have indexNil. */
+  if (aux_index == indexNil)
+    return mdebug_type_int;
+
+  /* Handle corrupt aux indices.  */
+  if (aux_index >= (debug_info->fdr + fd)->caux)
+    {
+      complain (&index_complaint, sym_name);
+      return mdebug_type_int;
+    }
+  ax += aux_index;
+
+  /* Use aux as a type information record, map its basic type.  */
+  (*debug_swap->swap_tir_in) (bigend, &ax->a_ti, t);
+  if (t->bt >= (sizeof (map_bt) / sizeof (*map_bt)))
+    {
+      complain (&basic_type_complaint, t->bt, sym_name);
+      return mdebug_type_int;
+    }
+  if (map_bt[t->bt])
+    {
+      tp = *map_bt[t->bt];
+    }
+  else
+    {
+      tp = NULL;
+      /* Cannot use builtin types -- build our own */
+      switch (t->bt)
+       {
+       case btStruct:
+         type_code = TYPE_CODE_STRUCT;
+         break;
+       case btUnion:
+         type_code = TYPE_CODE_UNION;
+         break;
+       case btEnum:
+         type_code = TYPE_CODE_ENUM;
+         break;
+       case btRange:
+         type_code = TYPE_CODE_RANGE;
+         break;
+       case btSet:
+         type_code = TYPE_CODE_SET;
+         break;
+       case btIndirect:
+         /* alpha cc -migrate uses this for typedefs. The true type will
+            be obtained by crossreferencing below.  */
+         type_code = TYPE_CODE_ERROR;
+         break;
+       case btTypedef:
+         /* alpha cc uses this for typedefs. The true type will be
+            obtained by crossreferencing below.  */
+         type_code = TYPE_CODE_ERROR;
+         break;
+       default:
+         complain (&basic_type_complaint, t->bt, sym_name);
+         return mdebug_type_int;
+       }
+    }
+
+  /* Move on to next aux */
+  ax++;
+
+  if (t->fBitfield)
+    {
+      int width = AUX_GET_WIDTH (bigend, ax);
+
+      /* Inhibit core dumps with some cfront generated objects that
+         corrupt the TIR.  */
+      if (bs == (int *) NULL)
+       {
+         /* Alpha cc -migrate encodes char and unsigned char types
+            as short and unsigned short types with a field width of 8.
+            Enum types also have a field width which we ignore for now.  */
+         if (t->bt == btShort && width == 8)
+           tp = mdebug_type_char;
+         else if (t->bt == btUShort && width == 8)
+           tp = mdebug_type_unsigned_char;
+         else if (t->bt == btEnum)
+           ;
+         else
+           complain (&bad_fbitfield_complaint, sym_name);
+       }
+      else
+       *bs = width;
+      ax++;
+    }
+
+  /* A btIndirect entry cross references to an aux entry containing
+     the type.  */
+  if (t->bt == btIndirect)
+    {
+      RNDXR rn[1];
+      int rf;
+      FDR *xref_fh;
+      int xref_fd;
+
+      (*debug_swap->swap_rndx_in) (bigend, &ax->a_rndx, rn);
+      ax++;
+      if (rn->rfd == 0xfff)
+       {
+         rf = AUX_GET_ISYM (bigend, ax);
+         ax++;
+       }
+      else
+       rf = rn->rfd;
+
+      if (rf == -1)
+       {
+         complain (&bad_indirect_xref_complaint, sym_name);
+         return mdebug_type_int;
+       }
+      xref_fh = get_rfd (fd, rf);
+      xref_fd = xref_fh - debug_info->fdr;
+      tp = parse_type (xref_fd, debug_info->external_aux + xref_fh->iauxBase,
+                   rn->index, (int *) NULL, xref_fh->fBigendian, sym_name);
+    }
+
+  /* All these types really point to some (common) MIPS type
+     definition, and only the type-qualifiers fully identify
+     them.  We'll make the same effort at sharing. */
+  if (t->bt == btStruct ||
+      t->bt == btUnion ||
+      t->bt == btEnum ||
+
+  /* btSet (I think) implies that the name is a tag name, not a typedef
+     name.  This apparently is a MIPS extension for C sets.  */
+      t->bt == btSet)
+    {
+      char *name;
+
+      /* Try to cross reference this type, build new type on failure.  */
+      ax += cross_ref (fd, ax, &tp, type_code, &name, bigend, sym_name);
+      if (tp == (struct type *) NULL)
+       tp = init_type (type_code, 0, 0, (char *) NULL, current_objfile);
+
+      /* DEC c89 produces cross references to qualified aggregate types,
+         dereference them.  */
+      while (TYPE_CODE (tp) == TYPE_CODE_PTR
+            || TYPE_CODE (tp) == TYPE_CODE_ARRAY)
+       tp = TYPE_TARGET_TYPE (tp);
+
+      /* Make sure that TYPE_CODE(tp) has an expected type code.
+         Any type may be returned from cross_ref if file indirect entries
+         are corrupted.  */
+      if (TYPE_CODE (tp) != TYPE_CODE_STRUCT
+         && TYPE_CODE (tp) != TYPE_CODE_UNION
+         && TYPE_CODE (tp) != TYPE_CODE_ENUM)
+       {
+         complain (&unexpected_type_code_complaint, sym_name);
+       }
+      else
+       {
+
+         /* Usually, TYPE_CODE(tp) is already type_code.  The main
+            exception is if we guessed wrong re struct/union/enum.
+            But for struct vs. union a wrong guess is harmless, so
+            don't complain().  */
+         if ((TYPE_CODE (tp) == TYPE_CODE_ENUM
+              && type_code != TYPE_CODE_ENUM)
+             || (TYPE_CODE (tp) != TYPE_CODE_ENUM
+                 && type_code == TYPE_CODE_ENUM))
+           {
+             complain (&bad_tag_guess_complaint, sym_name);
+           }
+
+         if (TYPE_CODE (tp) != type_code)
+           {
+             TYPE_CODE (tp) = type_code;
+           }
+
+         /* Do not set the tag name if it is a compiler generated tag name
+            (.Fxx or .xxfake or empty) for unnamed struct/union/enums.  */
+         if (name[0] == '.' || name[0] == '\0')
+           TYPE_TAG_NAME (tp) = NULL;
+         else if (TYPE_TAG_NAME (tp) == NULL
+                  || !STREQ (TYPE_TAG_NAME (tp), name))
+           TYPE_TAG_NAME (tp) = obsavestring (name, strlen (name),
+                                           &current_objfile->type_obstack);
+       }
+    }
+
+  /* All these types really point to some (common) MIPS type
+     definition, and only the type-qualifiers fully identify
+     them.  We'll make the same effort at sharing.
+     FIXME: We are not doing any guessing on range types.  */
+  if (t->bt == btRange)
+    {
+      char *name;
+
+      /* Try to cross reference this type, build new type on failure.  */
+      ax += cross_ref (fd, ax, &tp, type_code, &name, bigend, sym_name);
+      if (tp == (struct type *) NULL)
+       tp = init_type (type_code, 0, 0, (char *) NULL, current_objfile);
+
+      /* Make sure that TYPE_CODE(tp) has an expected type code.
+         Any type may be returned from cross_ref if file indirect entries
+         are corrupted.  */
+      if (TYPE_CODE (tp) != TYPE_CODE_RANGE)
+       {
+         complain (&unexpected_type_code_complaint, sym_name);
+       }
+      else
+       {
+         /* Usually, TYPE_CODE(tp) is already type_code.  The main
+            exception is if we guessed wrong re struct/union/enum. */
+         if (TYPE_CODE (tp) != type_code)
+           {
+             complain (&bad_tag_guess_complaint, sym_name);
+             TYPE_CODE (tp) = type_code;
+           }
+         if (TYPE_NAME (tp) == NULL || !STREQ (TYPE_NAME (tp), name))
+           TYPE_NAME (tp) = obsavestring (name, strlen (name),
+                                          &current_objfile->type_obstack);
+       }
+    }
+  if (t->bt == btTypedef)
+    {
+      char *name;
+
+      /* Try to cross reference this type, it should succeed.  */
+      ax += cross_ref (fd, ax, &tp, type_code, &name, bigend, sym_name);
+      if (tp == (struct type *) NULL)
+       {
+         complain (&unable_to_cross_ref_complaint, sym_name);
+         tp = mdebug_type_int;
+       }
+    }
+
+  /* Deal with range types */
+  if (t->bt == btRange)
+    {
+      TYPE_NFIELDS (tp) = 2;
+      TYPE_FIELDS (tp) = ((struct field *)
+                         TYPE_ALLOC (tp, 2 * sizeof (struct field)));
+      TYPE_FIELD_NAME (tp, 0) = obsavestring ("Low", strlen ("Low"),
+                                           &current_objfile->type_obstack);
+      TYPE_FIELD_BITPOS (tp, 0) = AUX_GET_DNLOW (bigend, ax);
+      ax++;
+      TYPE_FIELD_NAME (tp, 1) = obsavestring ("High", strlen ("High"),
+                                           &current_objfile->type_obstack);
+      TYPE_FIELD_BITPOS (tp, 1) = AUX_GET_DNHIGH (bigend, ax);
+      ax++;
+    }
+
+  /* Parse all the type qualifiers now. If there are more
+     than 6 the game will continue in the next aux */
+
+  while (1)
+    {
+#define PARSE_TQ(tq) \
+      if (t->tq != tqNil) \
+       ax += upgrade_type(fd, &tp, t->tq, ax, bigend, sym_name); \
+      else \
+       break;
+
+      PARSE_TQ (tq0);
+      PARSE_TQ (tq1);
+      PARSE_TQ (tq2);
+      PARSE_TQ (tq3);
+      PARSE_TQ (tq4);
+      PARSE_TQ (tq5);
+#undef PARSE_TQ
+
+      /* mips cc 2.x and gcc never put out continued aux entries.  */
+      if (!t->continued)
+       break;
+
+      (*debug_swap->swap_tir_in) (bigend, &ax->a_ti, t);
+      ax++;
+    }
+
+  /* Complain for illegal continuations due to corrupt aux entries.  */
+  if (t->continued)
+    complain (&bad_continued_complaint, sym_name);
+
+  return tp;
+}
+
+/* Make up a complex type from a basic one.  Type is passed by
+   reference in TPP and side-effected as necessary. The type
+   qualifier TQ says how to handle the aux symbols at AX for
+   the symbol SX we are currently analyzing.  BIGEND says whether
+   aux symbols are big-endian or little-endian.
+   Returns the number of aux symbols we parsed. */
+
+static int
+upgrade_type (int fd, struct type **tpp, int tq, union aux_ext *ax, int bigend,
+             char *sym_name)
+{
+  int off;
+  struct type *t;
+
+  /* Used in array processing */
+  int rf, id;
+  FDR *fh;
+  struct type *range;
+  struct type *indx;
+  int lower, upper;
+  RNDXR rndx;
+
+  switch (tq)
+    {
+    case tqPtr:
+      t = lookup_pointer_type (*tpp);
+      *tpp = t;
+      return 0;
+
+    case tqProc:
+      t = lookup_function_type (*tpp);
+      *tpp = t;
+      return 0;
+
+    case tqArray:
+      off = 0;
+
+      /* Determine and record the domain type (type of index) */
+      (*debug_swap->swap_rndx_in) (bigend, &ax->a_rndx, &rndx);
+      id = rndx.index;
+      rf = rndx.rfd;
+      if (rf == 0xfff)
+       {
+         ax++;
+         rf = AUX_GET_ISYM (bigend, ax);
+         off++;
+       }
+      fh = get_rfd (fd, rf);
+
+      indx = parse_type (fh - debug_info->fdr,
+                        debug_info->external_aux + fh->iauxBase,
+                        id, (int *) NULL, bigend, sym_name);
+
+      /* The bounds type should be an integer type, but might be anything
+         else due to corrupt aux entries.  */
+      if (TYPE_CODE (indx) != TYPE_CODE_INT)
+       {
+         complain (&array_index_type_complaint, sym_name);
+         indx = mdebug_type_int;
+       }
+
+      /* Get the bounds, and create the array type.  */
+      ax++;
+      lower = AUX_GET_DNLOW (bigend, ax);
+      ax++;
+      upper = AUX_GET_DNHIGH (bigend, ax);
+      ax++;
+      rf = AUX_GET_WIDTH (bigend, ax); /* bit size of array element */
+
+      range = create_range_type ((struct type *) NULL, indx,
+                                lower, upper);
+
+      t = create_array_type ((struct type *) NULL, *tpp, range);
+
+      /* We used to fill in the supplied array element bitsize
+         here if the TYPE_LENGTH of the target type was zero.
+         This happens for a `pointer to an array of anonymous structs',
+         but in this case the array element bitsize is also zero,
+         so nothing is gained.
+         And we used to check the TYPE_LENGTH of the target type against
+         the supplied array element bitsize.
+         gcc causes a mismatch for `pointer to array of object',
+         since the sdb directives it uses do not have a way of
+         specifying the bitsize, but it does no harm (the
+         TYPE_LENGTH should be correct) and we should be able to
+         ignore the erroneous bitsize from the auxiliary entry safely.
+         dbx seems to ignore it too.  */
+
+      /* TYPE_FLAG_TARGET_STUB now takes care of the zero TYPE_LENGTH
+         problem.  */
+      if (TYPE_LENGTH (*tpp) == 0)
+       {
+         TYPE_FLAGS (t) |= TYPE_FLAG_TARGET_STUB;
+       }
+
+      *tpp = t;
+      return 4 + off;
+
+    case tqVol:
+      /* Volatile -- currently ignored */
+      return 0;
+
+    case tqConst:
+      /* Const -- currently ignored */
+      return 0;
+
+    default:
+      complain (&unknown_type_qual_complaint, tq);
+      return 0;
+    }
+}
+
+
+/* Parse a procedure descriptor record PR.  Note that the procedure is
+   parsed _after_ the local symbols, now we just insert the extra
+   information we need into a MIPS_EFI_SYMBOL_NAME symbol that has
+   already been placed in the procedure's main block.  Note also that
+   images that have been partially stripped (ld -x) have been deprived
+   of local symbols, and we have to cope with them here.  FIRST_OFF is
+   the offset of the first procedure for this FDR; we adjust the
+   address by this amount, but I don't know why.  SEARCH_SYMTAB is the symtab
+   to look for the function which contains the MIPS_EFI_SYMBOL_NAME symbol
+   in question, or NULL to use top_stack->cur_block.  */
+
+static void parse_procedure (PDR *, struct symtab *, struct partial_symtab *);
+
+static void
+parse_procedure (PDR *pr, struct symtab *search_symtab,
+                struct partial_symtab *pst)
+{
+  struct symbol *s, *i;
+  struct block *b;
+  struct mips_extra_func_info *e;
+  char *sh_name;
+
+  /* Simple rule to find files linked "-x" */
+  if (cur_fdr->rss == -1)
+    {
+      if (pr->isym == -1)
+       {
+         /* Static procedure at address pr->adr.  Sigh. */
+         /* FIXME-32x64.  assuming pr->adr fits in long.  */
+         complain (&pdr_static_symbol_complaint, (unsigned long) pr->adr);
+         return;
+       }
+      else
+       {
+         /* external */
+         EXTR she;
+
+         (*debug_swap->swap_ext_in) (cur_bfd,
+                                     ((char *) debug_info->external_ext
+                                      + (pr->isym
+                                         * debug_swap->external_ext_size)),
+                                     &she);
+         sh_name = debug_info->ssext + she.asym.iss;
+       }
+    }
+  else
+    {
+      /* Full symbols */
+      SYMR sh;
+
+      (*debug_swap->swap_sym_in) (cur_bfd,
+                                 ((char *) debug_info->external_sym
+                                  + ((cur_fdr->isymBase + pr->isym)
+                                     * debug_swap->external_sym_size)),
+                                 &sh);
+      sh_name = debug_info->ss + cur_fdr->issBase + sh.iss;
+    }
+
+  if (search_symtab != NULL)
+    {
+#if 0
+      /* This loses both in the case mentioned (want a static, find a global),
+         but also if we are looking up a non-mangled name which happens to
+         match the name of a mangled function.  */
+      /* We have to save the cur_fdr across the call to lookup_symbol.
+         If the pdr is for a static function and if a global function with
+         the same name exists, lookup_symbol will eventually read in the symtab
+         for the global function and clobber cur_fdr.  */
+      FDR *save_cur_fdr = cur_fdr;
+      s = lookup_symbol (sh_name, NULL, VAR_NAMESPACE, 0, NULL);
+      cur_fdr = save_cur_fdr;
+#else
+      s = mylookup_symbol
+       (sh_name,
+        BLOCKVECTOR_BLOCK (BLOCKVECTOR (search_symtab), STATIC_BLOCK),
+        VAR_NAMESPACE,
+        LOC_BLOCK);
+#endif
+    }
+  else
+    s = mylookup_symbol (sh_name, top_stack->cur_block,
+                        VAR_NAMESPACE, LOC_BLOCK);
+
+  if (s != 0)
+    {
+      b = SYMBOL_BLOCK_VALUE (s);
+    }
+  else
+    {
+      complain (&pdr_for_nonsymbol_complaint, sh_name);
+#if 1
+      return;
+#else
+/* FIXME -- delete.  We can't do symbol allocation now; it's all done.  */
+      s = new_symbol (sh_name);
+      SYMBOL_NAMESPACE (s) = VAR_NAMESPACE;
+      SYMBOL_CLASS (s) = LOC_BLOCK;
+      /* Donno its type, hope int is ok */
+      SYMBOL_TYPE (s) = lookup_function_type (mdebug_type_int);
+      add_symbol (s, top_stack->cur_block);
+      /* Wont have symbols for this one */
+      b = new_block (2);
+      SYMBOL_BLOCK_VALUE (s) = b;
+      BLOCK_FUNCTION (b) = s;
+      BLOCK_START (b) = pr->adr;
+      /* BOUND used to be the end of procedure's text, but the
+         argument is no longer passed in.  */
+      BLOCK_END (b) = bound;
+      BLOCK_SUPERBLOCK (b) = top_stack->cur_block;
+      add_block (b, top_stack->cur_st);
+#endif
+    }
+
+  i = mylookup_symbol (MIPS_EFI_SYMBOL_NAME, b, LABEL_NAMESPACE, LOC_CONST);
+
+  if (i)
+    {
+      e = (struct mips_extra_func_info *) SYMBOL_VALUE (i);
+      e->pdr = *pr;
+      e->pdr.isym = (long) s;
+
+      /* GDB expects the absolute function start address for the
+         procedure descriptor in e->pdr.adr.
+         As the address in the procedure descriptor is usually relative,
+         we would have to relocate e->pdr.adr with cur_fdr->adr and
+         ANOFFSET (pst->section_offsets, SECT_OFF_TEXT (pst->objfile)).
+         Unfortunately cur_fdr->adr and e->pdr.adr are both absolute
+         in shared libraries on some systems, and on other systems
+         e->pdr.adr is sometimes offset by a bogus value.
+         To work around these problems, we replace e->pdr.adr with
+         the start address of the function.  */
+      e->pdr.adr = BLOCK_START (b);
+
+      /* Correct incorrect setjmp procedure descriptor from the library
+         to make backtrace through setjmp work.  */
+      if (e->pdr.pcreg == 0 && STREQ (sh_name, "setjmp"))
+       {
+         complain (&bad_setjmp_pdr_complaint, 0);
+         e->pdr.pcreg = RA_REGNUM;
+         e->pdr.regmask = 0x80000000;
+         e->pdr.regoffset = -4;
+       }
+    }
+
+  /* It would be reasonable that functions that have been compiled
+     without debugging info have a btNil type for their return value,
+     and functions that are void and are compiled with debugging info
+     have btVoid.
+     gcc and DEC f77 put out btNil types for both cases, so btNil is mapped
+     to TYPE_CODE_VOID in parse_type to get the `compiled with debugging info'
+     case right.
+     The glevel field in cur_fdr could be used to determine the presence
+     of debugging info, but GCC doesn't always pass the -g switch settings
+     to the assembler and GAS doesn't set the glevel field from the -g switch
+     settings.
+     To work around these problems, the return value type of a TYPE_CODE_VOID
+     function is adjusted accordingly if no debugging info was found in the
+     compilation unit.  */
+
+  if (processing_gcc_compilation == 0
+      && found_ecoff_debugging_info == 0
+      && TYPE_CODE (TYPE_TARGET_TYPE (SYMBOL_TYPE (s))) == TYPE_CODE_VOID)
+    SYMBOL_TYPE (s) = nodebug_func_symbol_type;
+}
+
+/* Relocate the extra function info pointed to by the symbol table.  */
+
+void
+ecoff_relocate_efi (struct symbol *sym, CORE_ADDR delta)
+{
+  struct mips_extra_func_info *e;
+
+  e = (struct mips_extra_func_info *) SYMBOL_VALUE (sym);
+
+  e->pdr.adr += delta;
+}
+
+/* Parse the external symbol ES. Just call parse_symbol() after
+   making sure we know where the aux are for it.
+   BIGEND says whether aux entries are big-endian or little-endian.
+
+   This routine clobbers top_stack->cur_block and ->cur_st. */
+
+static void parse_external (EXTR *, int, struct section_offsets *,
+                           struct objfile *);
+
+static void
+parse_external (EXTR *es, int bigend, struct section_offsets *section_offsets,
+               struct objfile *objfile)
+{
+  union aux_ext *ax;
+
+  if (es->ifd != ifdNil)
+    {
+      cur_fd = es->ifd;
+      cur_fdr = debug_info->fdr + cur_fd;
+      ax = debug_info->external_aux + cur_fdr->iauxBase;
+    }
+  else
+    {
+      cur_fdr = debug_info->fdr;
+      ax = 0;
+    }
+
+  /* Reading .o files */
+  if (SC_IS_UNDEF (es->asym.sc) || es->asym.sc == scNil)
+    {
+      char *what;
+      switch (es->asym.st)
+       {
+       case stNil:
+         /* These are generated for static symbols in .o files,
+            ignore them.  */
+         return;
+       case stStaticProc:
+       case stProc:
+         what = "procedure";
+         n_undef_procs++;
+         break;
+       case stGlobal:
+         what = "variable";
+         n_undef_vars++;
+         break;
+       case stLabel:
+         what = "label";
+         n_undef_labels++;
+         break;
+       default:
+         what = "symbol";
+         break;
+       }
+      n_undef_symbols++;
+      /* FIXME:  Turn this into a complaint? */
+      if (info_verbose)
+       printf_filtered ("Warning: %s `%s' is undefined (in %s)\n",
+                        what, debug_info->ssext + es->asym.iss,
+                        fdr_name (cur_fdr));
+      return;
+    }
+
+  switch (es->asym.st)
+    {
+    case stProc:
+    case stStaticProc:
+      /* There is no need to parse the external procedure symbols.
+         If they are from objects compiled without -g, their index will
+         be indexNil, and the symbol definition from the minimal symbol
+         is preferrable (yielding a function returning int instead of int).
+         If the index points to a local procedure symbol, the local
+         symbol already provides the correct type.
+         Note that the index of the external procedure symbol points
+         to the local procedure symbol in the local symbol table, and
+         _not_ to the auxiliary symbol info.  */
+      break;
+    case stGlobal:
+    case stLabel:
+      /* Global common symbols are resolved by the runtime loader,
+         ignore them.  */
+      if (SC_IS_COMMON (es->asym.sc))
+       break;
+
+      /* Note that the case of a symbol with indexNil must be handled
+         anyways by parse_symbol().  */
+      parse_symbol (&es->asym, ax, (char *) NULL, bigend, section_offsets, objfile);
+      break;
+    default:
+      break;
+    }
+}
+
+/* Parse the line number info for file descriptor FH into
+   GDB's linetable LT.  MIPS' encoding requires a little bit
+   of magic to get things out.  Note also that MIPS' line
+   numbers can go back and forth, apparently we can live
+   with that and do not need to reorder our linetables */
+
+static void parse_lines (FDR *, PDR *, struct linetable *, int,
+                        struct partial_symtab *, CORE_ADDR);
+
+static void
+parse_lines (FDR *fh, PDR *pr, struct linetable *lt, int maxlines,
+            struct partial_symtab *pst, CORE_ADDR lowest_pdr_addr)
+{
+  unsigned char *base;
+  int j, k;
+  int delta, count, lineno = 0;
+
+  if (fh->cbLine == 0)
+    return;
+
+  /* Scan by procedure descriptors */
+  k = 0;
+  for (j = 0; j < fh->cpd; j++, pr++)
+    {
+      CORE_ADDR l;
+      CORE_ADDR adr;
+      unsigned char *halt;
+
+      /* No code for this one */
+      if (pr->iline == ilineNil ||
+         pr->lnLow == -1 || pr->lnHigh == -1)
+       continue;
+
+      /* Determine start and end address of compressed line bytes for
+         this procedure.  */
+      base = debug_info->line + fh->cbLineOffset;
+      if (j != (fh->cpd - 1))
+       halt = base + pr[1].cbLineOffset;
+      else
+       halt = base + fh->cbLine;
+      base += pr->cbLineOffset;
+
+      adr = pst->textlow + pr->adr - lowest_pdr_addr;
+
+      l = adr >> 2;            /* in words */
+      for (lineno = pr->lnLow; base < halt;)
+       {
+         count = *base & 0x0f;
+         delta = *base++ >> 4;
+         if (delta >= 8)
+           delta -= 16;
+         if (delta == -8)
+           {
+             delta = (base[0] << 8) | base[1];
+             if (delta >= 0x8000)
+               delta -= 0x10000;
+             base += 2;
+           }
+         lineno += delta;      /* first delta is 0 */
+
+         /* Complain if the line table overflows. Could happen
+            with corrupt binaries.  */
+         if (lt->nitems >= maxlines)
+           {
+             complain (&bad_linetable_guess_complaint, fdr_name (fh));
+             break;
+           }
+         k = add_line (lt, lineno, l, k);
+         l += count + 1;
+       }
+    }
+}
+\f
+/* Master parsing procedure for first-pass reading of file symbols
+   into a partial_symtab.  */
+
+static void
+parse_partial_symbols (struct objfile *objfile)
+{
+  const bfd_size_type external_sym_size = debug_swap->external_sym_size;
+  const bfd_size_type external_rfd_size = debug_swap->external_rfd_size;
+  const bfd_size_type external_ext_size = debug_swap->external_ext_size;
+  void (*const swap_ext_in) (bfd *, void *, EXTR *) = debug_swap->swap_ext_in;
+  void (*const swap_sym_in) (bfd *, void *, SYMR *) = debug_swap->swap_sym_in;
+  void (*const swap_rfd_in) (bfd *, void *, RFDT *) = debug_swap->swap_rfd_in;
+  int f_idx, s_idx;
+  HDRR *hdr = &debug_info->symbolic_header;
+  /* Running pointers */
+  FDR *fh;
+  char *ext_out;
+  char *ext_out_end;
+  EXTR *ext_block;
+  register EXTR *ext_in;
+  EXTR *ext_in_end;
+  SYMR sh;
+  struct partial_symtab *pst;
+  int textlow_not_set = 1;
+  int past_first_source_file = 0;
+
+  /* List of current psymtab's include files */
+  char **psymtab_include_list;
+  int includes_allocated;
+  int includes_used;
+  EXTR *extern_tab;
+  struct pst_map *fdr_to_pst;
+  /* Index within current psymtab dependency list */
+  struct partial_symtab **dependency_list;
+  int dependencies_used, dependencies_allocated;
+  struct cleanup *old_chain;
+  char *name;
+  enum language prev_language;
+  asection *text_sect;
+  int relocatable = 0;
+
+  /* Irix 5.2 shared libraries have a fh->adr field of zero, but
+     the shared libraries are prelinked at a high memory address.
+     We have to adjust the start address of the object file for this case,
+     by setting it to the start address of the first procedure in the file.
+     But we should do no adjustments if we are debugging a .o file, where
+     the text section (and fh->adr) really starts at zero.  */
+  text_sect = bfd_get_section_by_name (cur_bfd, ".text");
+  if (text_sect != NULL
+      && (bfd_get_section_flags (cur_bfd, text_sect) & SEC_RELOC))
+    relocatable = 1;
+
+  extern_tab = (EXTR *) obstack_alloc (&objfile->psymbol_obstack,
+                                      sizeof (EXTR) * hdr->iextMax);
+
+  includes_allocated = 30;
+  includes_used = 0;
+  psymtab_include_list = (char **) alloca (includes_allocated *
+                                          sizeof (char *));
+  next_symbol_text_func = mdebug_next_symbol_text;
+
+  dependencies_allocated = 30;
+  dependencies_used = 0;
+  dependency_list =
+    (struct partial_symtab **) alloca (dependencies_allocated *
+                                      sizeof (struct partial_symtab *));
+
+  last_source_file = NULL;
+
+  /*
+   * Big plan:
+   *
+   * Only parse the Local and External symbols, and the Relative FDR.
+   * Fixup enough of the loader symtab to be able to use it.
+   * Allocate space only for the file's portions we need to
+   * look at. (XXX)
+   */
+
+  max_gdbinfo = 0;
+  max_glevel = MIN_GLEVEL;
+
+  /* Allocate the map FDR -> PST.
+     Minor hack: -O3 images might claim some global data belongs
+     to FDR -1. We`ll go along with that */
+  fdr_to_pst = (struct pst_map *) xzalloc ((hdr->ifdMax + 1) * sizeof *fdr_to_pst);
+  old_chain = make_cleanup (xfree, fdr_to_pst);
+  fdr_to_pst++;
+  {
+    struct partial_symtab *pst = new_psymtab ("", objfile);
+    fdr_to_pst[-1].pst = pst;
+    FDR_IDX (pst) = -1;
+  }
+
+  /* Allocate the global pending list.  */
+  pending_list =
+    ((struct mdebug_pending **)
+     obstack_alloc (&objfile->psymbol_obstack,
+                   hdr->ifdMax * sizeof (struct mdebug_pending *)));
+  memset (pending_list, 0,
+         hdr->ifdMax * sizeof (struct mdebug_pending *));
+
+  /* Pass 0 over external syms: swap them in.  */
+  ext_block = (EXTR *) xmalloc (hdr->iextMax * sizeof (EXTR));
+  make_cleanup (xfree, ext_block);
+
+  ext_out = (char *) debug_info->external_ext;
+  ext_out_end = ext_out + hdr->iextMax * external_ext_size;
+  ext_in = ext_block;
+  for (; ext_out < ext_out_end; ext_out += external_ext_size, ext_in++)
+    (*swap_ext_in) (cur_bfd, ext_out, ext_in);
+
+  /* Pass 1 over external syms: Presize and partition the list */
+  ext_in = ext_block;
+  ext_in_end = ext_in + hdr->iextMax;
+  for (; ext_in < ext_in_end; ext_in++)
+    {
+      /* See calls to complain below.  */
+      if (ext_in->ifd >= -1
+         && ext_in->ifd < hdr->ifdMax
+         && ext_in->asym.iss >= 0
+         && ext_in->asym.iss < hdr->issExtMax)
+       fdr_to_pst[ext_in->ifd].n_globals++;
+    }
+
+  /* Pass 1.5 over files:  partition out global symbol space */
+  s_idx = 0;
+  for (f_idx = -1; f_idx < hdr->ifdMax; f_idx++)
+    {
+      fdr_to_pst[f_idx].globals_offset = s_idx;
+      s_idx += fdr_to_pst[f_idx].n_globals;
+      fdr_to_pst[f_idx].n_globals = 0;
+    }
+
+  /* ECOFF in ELF:
+
+     For ECOFF in ELF, we skip the creation of the minimal symbols.
+     The ECOFF symbols should be a subset of the Elf symbols, and the 
+     section information of the elf symbols will be more accurate.
+     FIXME!  What about Irix 5's native linker?
+
+     By default, Elf sections which don't exist in ECOFF 
+     get put in ECOFF's absolute section by the gnu linker.
+     Since absolute sections don't get relocated, we 
+     end up calculating an address different from that of 
+     the symbol's minimal symbol (created earlier from the
+     Elf symtab).  
+
+     To fix this, either :
+     1) don't create the duplicate symbol
+     (assumes ECOFF symtab is a subset of the ELF symtab;
+     assumes no side-effects result from ignoring ECOFF symbol)
+     2) create it, only if lookup for existing symbol in ELF's minimal 
+     symbols fails
+     (inefficient; 
+     assumes no side-effects result from ignoring ECOFF symbol)
+     3) create it, but lookup ELF's minimal symbol and use it's section
+     during relocation, then modify "uniqify" phase to merge and 
+     eliminate the duplicate symbol
+     (highly inefficient)
+
+     I've implemented #1 here...
+     Skip the creation of the minimal symbols based on the ECOFF 
+     symbol table. */
+
+  /* Pass 2 over external syms: fill in external symbols */
+  ext_in = ext_block;
+  ext_in_end = ext_in + hdr->iextMax;
+  for (; ext_in < ext_in_end; ext_in++)
+    {
+      enum minimal_symbol_type ms_type = mst_text;
+      CORE_ADDR svalue = ext_in->asym.value;
+
+      /* The Irix 5 native tools seem to sometimes generate bogus
+         external symbols.  */
+      if (ext_in->ifd < -1 || ext_in->ifd >= hdr->ifdMax)
+       {
+         complain (&bad_ext_ifd_complaint, ext_in->ifd, hdr->ifdMax);
+         continue;
+       }
+      if (ext_in->asym.iss < 0 || ext_in->asym.iss >= hdr->issExtMax)
+       {
+         complain (&bad_ext_iss_complaint, ext_in->asym.iss,
+                   hdr->issExtMax);
+         continue;
+       }
+
+      extern_tab[fdr_to_pst[ext_in->ifd].globals_offset
+                + fdr_to_pst[ext_in->ifd].n_globals++] = *ext_in;
+
+
+      if (SC_IS_UNDEF (ext_in->asym.sc) || ext_in->asym.sc == scNil)
+       continue;
+
+
+      /* Pass 3 over files, over local syms: fill in static symbols */
+      name = debug_info->ssext + ext_in->asym.iss;
+
+      /* Process ECOFF Symbol Types and Storage Classes */
+      switch (ext_in->asym.st)
+       {
+       case stProc:
+         /* Beginnning of Procedure */
+         svalue += ANOFFSET (objfile->section_offsets, SECT_OFF_TEXT (objfile));
+         break;
+       case stStaticProc:
+         /* Load time only static procs */
+         ms_type = mst_file_text;
+         svalue += ANOFFSET (objfile->section_offsets, SECT_OFF_TEXT (objfile));
+         break;
+       case stGlobal:
+         /* External symbol */
+         if (SC_IS_COMMON (ext_in->asym.sc))
+           {
+             /* The value of a common symbol is its size, not its address.
+                Ignore it.  */
+             continue;
+           }
+         else if (SC_IS_DATA (ext_in->asym.sc))
+           {
+             ms_type = mst_data;
+             svalue += ANOFFSET (objfile->section_offsets, SECT_OFF_DATA (objfile));
+           }
+         else if (SC_IS_BSS (ext_in->asym.sc))
+           {
+             ms_type = mst_bss;
+             svalue += ANOFFSET (objfile->section_offsets, SECT_OFF_BSS (objfile));
+           }
+          else if (SC_IS_SBSS (ext_in->asym.sc))
+            {
+              ms_type = mst_bss;
+              svalue += ANOFFSET (objfile->section_offsets, 
+                                  get_section_index (objfile, ".sbss"));
+            }
+         else
+           ms_type = mst_abs;
+         break;
+       case stLabel:
+         /* Label */
+
+          /* On certain platforms, some extra label symbols can be
+             generated by the linker. One possible usage for this kind
+             of symbols is to represent the address of the begining of a
+             given section. For instance, on Tru64 5.1, the address of
+             the _ftext label is the start address of the .text section.
+
+             The storage class of these symbols is usually directly
+             related to the section to which the symbol refers. For
+             instance, on Tru64 5.1, the storage class for the _fdata
+             label is scData, refering to the .data section.
+
+             It is actually possible that the section associated to the
+             storage class of the label does not exist. On True64 5.1
+             for instance, the libm.so shared library does not contain
+             any .data section, although it contains a _fpdata label
+             which storage class is scData... Since these symbols are
+             usually useless for the debugger user anyway, we just
+             discard these symbols.
+           */
+          
+         if (SC_IS_TEXT (ext_in->asym.sc))
+           {
+              if (objfile->sect_index_text == -1)
+                continue;
+                
+             ms_type = mst_file_text;
+             svalue += ANOFFSET (objfile->section_offsets, SECT_OFF_TEXT (objfile));
+           }
+         else if (SC_IS_DATA (ext_in->asym.sc))
+           {
+              if (objfile->sect_index_data == -1)
+                continue;
+
+             ms_type = mst_file_data;
+             svalue += ANOFFSET (objfile->section_offsets, SECT_OFF_DATA (objfile));
+           }
+         else if (SC_IS_BSS (ext_in->asym.sc))
+           {
+              if (objfile->sect_index_bss == -1)
+                continue;
+
+             ms_type = mst_file_bss;
+             svalue += ANOFFSET (objfile->section_offsets, SECT_OFF_BSS (objfile));
+           }
+          else if (SC_IS_SBSS (ext_in->asym.sc))
+            {
+              const int sbss_sect_index = get_section_index (objfile, ".sbss");
+
+              if (sbss_sect_index == -1)
+                continue;
+
+              ms_type = mst_file_bss;
+              svalue += ANOFFSET (objfile->section_offsets, sbss_sect_index);
+            }
+         else
+           ms_type = mst_abs;
+         break;
+       case stLocal:
+       case stNil:
+         /* The alpha has the section start addresses in stLocal symbols
+            whose name starts with a `.'. Skip those but complain for all
+            other stLocal symbols.
+            Irix6 puts the section start addresses in stNil symbols, skip
+            those too. */
+         if (name[0] == '.')
+           continue;
+         /* Fall through.  */
+       default:
+         ms_type = mst_unknown;
+         complain (&unknown_ext_complaint, name);
+       }
+      if (!ECOFF_IN_ELF (cur_bfd))
+       prim_record_minimal_symbol (name, svalue, ms_type, objfile);
+    }
+
+  /* Pass 3 over files, over local syms: fill in static symbols */
+  for (f_idx = 0; f_idx < hdr->ifdMax; f_idx++)
+    {
+      struct partial_symtab *save_pst;
+      EXTR *ext_ptr;
+      CORE_ADDR textlow;
+
+      cur_fdr = fh = debug_info->fdr + f_idx;
+
+      if (fh->csym == 0)
+       {
+         fdr_to_pst[f_idx].pst = NULL;
+         continue;
+       }
+
+      /* Determine the start address for this object file from the
+         file header and relocate it, except for Irix 5.2 zero fh->adr.  */
+      if (fh->cpd)
+       {
+         textlow = fh->adr;
+         if (relocatable || textlow != 0)
+           textlow += ANOFFSET (objfile->section_offsets, SECT_OFF_TEXT (objfile));
+       }
+      else
+       textlow = 0;
+      pst = start_psymtab_common (objfile, objfile->section_offsets,
+                                 fdr_name (fh),
+                                 textlow,
+                                 objfile->global_psymbols.next,
+                                 objfile->static_psymbols.next);
+      pst->read_symtab_private = ((char *)
+                                 obstack_alloc (&objfile->psymbol_obstack,
+                                                sizeof (struct symloc)));
+      memset (pst->read_symtab_private, 0, sizeof (struct symloc));
+
+      save_pst = pst;
+      FDR_IDX (pst) = f_idx;
+      CUR_BFD (pst) = cur_bfd;
+      DEBUG_SWAP (pst) = debug_swap;
+      DEBUG_INFO (pst) = debug_info;
+      PENDING_LIST (pst) = pending_list;
+
+      /* The way to turn this into a symtab is to call... */
+      pst->read_symtab = mdebug_psymtab_to_symtab;
+
+      /* Set up language for the pst.
+         The language from the FDR is used if it is unambigious (e.g. cfront
+         with native cc and g++ will set the language to C).
+         Otherwise we have to deduce the language from the filename.
+         Native ecoff has every header file in a separate FDR, so
+         deduce_language_from_filename will return language_unknown for
+         a header file, which is not what we want.
+         But the FDRs for the header files are after the FDR for the source
+         file, so we can assign the language of the source file to the
+         following header files. Then we save the language in the private
+         pst data so that we can reuse it when building symtabs.  */
+      prev_language = psymtab_language;
+
+      switch (fh->lang)
+       {
+       case langCplusplusV2:
+         psymtab_language = language_cplus;
+         break;
+       default:
+         psymtab_language = deduce_language_from_filename (fdr_name (fh));
+         break;
+       }
+      if (psymtab_language == language_unknown)
+       psymtab_language = prev_language;
+      PST_PRIVATE (pst)->pst_language = psymtab_language;
+
+      pst->texthigh = pst->textlow;
+
+      /* For stabs-in-ecoff files, the second symbol must be @stab.
+         This symbol is emitted by mips-tfile to signal that the
+         current object file uses encapsulated stabs instead of mips
+         ecoff for local symbols.  (It is the second symbol because
+         the first symbol is the stFile used to signal the start of a
+         file). */
+      processing_gcc_compilation = 0;
+      if (fh->csym >= 2)
+       {
+         (*swap_sym_in) (cur_bfd,
+                         ((char *) debug_info->external_sym
+                          + (fh->isymBase + 1) * external_sym_size),
+                         &sh);
+         if (STREQ (debug_info->ss + fh->issBase + sh.iss, stabs_symbol))
+           processing_gcc_compilation = 2;
+       }
+
+      if (processing_gcc_compilation != 0)
+       {
+         for (cur_sdx = 2; cur_sdx < fh->csym; cur_sdx++)
+           {
+             int type_code;
+             char *namestring;
+
+             (*swap_sym_in) (cur_bfd,
+                             (((char *) debug_info->external_sym)
+                           + (fh->isymBase + cur_sdx) * external_sym_size),
+                             &sh);
+             type_code = ECOFF_UNMARK_STAB (sh.index);
+             if (!ECOFF_IS_STAB (&sh))
+               {
+                 if (sh.st == stProc || sh.st == stStaticProc)
+                   {
+                     CORE_ADDR procaddr;
+                     long isym;
+
+                     sh.value += ANOFFSET (objfile->section_offsets, SECT_OFF_TEXT (objfile));
+                     if (sh.st == stStaticProc)
+                       {
+                         namestring = debug_info->ss + fh->issBase + sh.iss;
+                         prim_record_minimal_symbol_and_info (namestring,
+                                                              sh.value,
+                                                              mst_file_text,
+                                                              NULL,
+                                                              SECT_OFF_TEXT (objfile),
+                                                              NULL,
+                                                              objfile);
+                       }
+                     procaddr = sh.value;
+
+                     isym = AUX_GET_ISYM (fh->fBigendian,
+                                          (debug_info->external_aux
+                                           + fh->iauxBase
+                                           + sh.index));
+                     (*swap_sym_in) (cur_bfd,
+                                     ((char *) debug_info->external_sym
+                                      + ((fh->isymBase + isym - 1)
+                                         * external_sym_size)),
+                                     &sh);
+                     if (sh.st == stEnd)
+                       {
+                         CORE_ADDR high = procaddr + sh.value;
+
+                         /* Kludge for Irix 5.2 zero fh->adr.  */
+                         if (!relocatable
+                         && (pst->textlow == 0 || procaddr < pst->textlow))
+                           pst->textlow = procaddr;
+                         if (high > pst->texthigh)
+                           pst->texthigh = high;
+                       }
+                   }
+                 else if (sh.st == stStatic)
+                   {
+                     switch (sh.sc)
+                       {
+                       case scUndefined:
+                       case scSUndefined:
+                       case scNil:
+                       case scAbs:
+                         break;
+
+                       case scData:
+                       case scSData:
+                       case scRData:
+                       case scPData:
+                       case scXData:
+                         namestring = debug_info->ss + fh->issBase + sh.iss;
+                         sh.value += ANOFFSET (objfile->section_offsets, SECT_OFF_DATA (objfile));
+                         prim_record_minimal_symbol_and_info (namestring,
+                                                              sh.value,
+                                                              mst_file_data,
+                                                              NULL,
+                                                              SECT_OFF_DATA (objfile),
+                                                              NULL,
+                                                              objfile);
+                         break;
+
+                       default:
+                         /* FIXME!  Shouldn't this use cases for bss, 
+                            then have the default be abs? */
+                         namestring = debug_info->ss + fh->issBase + sh.iss;
+                         sh.value += ANOFFSET (objfile->section_offsets, SECT_OFF_BSS (objfile));
+                         prim_record_minimal_symbol_and_info (namestring,
+                                                              sh.value,
+                                                              mst_file_bss,
+                                                              NULL,
+                                                              SECT_OFF_BSS (objfile),
+                                                              NULL,
+                                                              objfile);
+                         break;
+                       }
+                   }
+                 continue;
+               }
+             /* Handle stabs continuation */
+             {
+               char *stabstring = debug_info->ss + fh->issBase + sh.iss;
+               int len = strlen (stabstring);
+               while (stabstring[len - 1] == '\\')
+                 {
+                   SYMR sh2;
+                   char *stabstring1 = stabstring;
+                   char *stabstring2;
+                   int len2;
+
+                   /* Ignore continuation char from 1st string */
+                   len--;
+
+                   /* Read next stabstring */
+                   cur_sdx++;
+                   (*swap_sym_in) (cur_bfd,
+                                   (((char *) debug_info->external_sym)
+                                    + (fh->isymBase + cur_sdx)
+                                    * external_sym_size),
+                                   &sh2);
+                   stabstring2 = debug_info->ss + fh->issBase + sh2.iss;
+                   len2 = strlen (stabstring2);
+
+                   /* Concatinate stabstring2 with stabstring1 */
+                   if (stabstring
+                    && stabstring != debug_info->ss + fh->issBase + sh.iss)
+                     stabstring = xrealloc (stabstring, len + len2 + 1);
+                   else
+                     {
+                       stabstring = xmalloc (len + len2 + 1);
+                       strcpy (stabstring, stabstring1);
+                     }
+                   strcpy (stabstring + len, stabstring2);
+                   len += len2;
+                 }
+
+               switch (type_code)
+                 {
+                   static struct complaint function_outside_compilation_unit = {
+                     "function `%s' appears to be defined outside of all compilation units", 0, 0
+                   };
+                   char *p;
+                   /*
+                    * Standard, external, non-debugger, symbols
+                    */
+
+                 case N_TEXT | N_EXT:
+                 case N_NBTEXT | N_EXT:
+                   sh.value += ANOFFSET (objfile->section_offsets, SECT_OFF_TEXT (objfile));
+                   goto record_it;
+
+                 case N_DATA | N_EXT:
+                 case N_NBDATA | N_EXT:
+                   sh.value += ANOFFSET (objfile->section_offsets, SECT_OFF_DATA (objfile));
+                   goto record_it;
+
+                 case N_BSS:
+                 case N_BSS | N_EXT:
+                 case N_NBBSS | N_EXT:
+                 case N_SETV | N_EXT:          /* FIXME, is this in BSS? */
+                   sh.value += ANOFFSET (objfile->section_offsets, SECT_OFF_BSS (objfile));
+                   goto record_it;
+
+                 case N_ABS | N_EXT:
+                 record_it:
+                 continue;
+
+                 /* Standard, local, non-debugger, symbols */
+
+                 case N_NBTEXT:
+
+                   /* We need to be able to deal with both N_FN or N_TEXT,
+                      because we have no way of knowing whether the sys-supplied ld
+                      or GNU ld was used to make the executable.  Sequents throw
+                      in another wrinkle -- they renumbered N_FN.  */
+
+                 case N_FN:
+                 case N_FN_SEQ:
+                 case N_TEXT:
+                   continue;
+
+                 case N_DATA:
+                   sh.value += ANOFFSET (objfile->section_offsets, SECT_OFF_DATA (objfile));
+                   goto record_it;
+
+                 case N_UNDF | N_EXT:
+                   continue;                   /* Just undefined, not COMMON */
+
+                 case N_UNDF:
+                   continue;
+
+                   /* Lots of symbol types we can just ignore.  */
+
+                 case N_ABS:
+                 case N_NBDATA:
+                 case N_NBBSS:
+                   continue;
+
+                   /* Keep going . . . */
+
+                   /*
+                    * Special symbol types for GNU
+                    */
+                 case N_INDR:
+                 case N_INDR | N_EXT:
+                 case N_SETA:
+                 case N_SETA | N_EXT:
+                 case N_SETT:
+                 case N_SETT | N_EXT:
+                 case N_SETD:
+                 case N_SETD | N_EXT:
+                 case N_SETB:
+                 case N_SETB | N_EXT:
+                 case N_SETV:
+                   continue;
+
+                   /*
+                    * Debugger symbols
+                    */
+
+                 case N_SO:
+                   {
+                     CORE_ADDR valu;
+                     static int prev_so_symnum = -10;
+                     static int first_so_symnum;
+                     char *p;
+                     int prev_textlow_not_set;
+
+                     valu = sh.value + ANOFFSET (objfile->section_offsets, SECT_OFF_TEXT (objfile));
+
+                     prev_textlow_not_set = textlow_not_set;
+
+#ifdef SOFUN_ADDRESS_MAYBE_MISSING
+                     /* A zero value is probably an indication for the SunPRO 3.0
+                        compiler. end_psymtab explicitly tests for zero, so
+                        don't relocate it.  */
+
+                     if (sh.value == 0)
+                       {
+                         textlow_not_set = 1;
+                         valu = 0;
+                       }
+                     else
+                       textlow_not_set = 0;
+#else
+                     textlow_not_set = 0;
+#endif
+                     past_first_source_file = 1;
+
+                     if (prev_so_symnum != symnum - 1)
+                       {                       /* Here if prev stab wasn't N_SO */
+                         first_so_symnum = symnum;
+
+                         if (pst)
+                           {
+                             pst = (struct partial_symtab *) 0;
+                             includes_used = 0;
+                             dependencies_used = 0;
+                           }
+                       }
+
+                     prev_so_symnum = symnum;
+
+                     /* End the current partial symtab and start a new one */
+
+                     /* SET_NAMESTRING ();*/
+                     namestring = stabstring;
+
+                     /* Null name means end of .o file.  Don't start a new one. */
+                     if (*namestring == '\000')
+                       continue;
+
+                     /* Some compilers (including gcc) emit a pair of initial N_SOs.
+                        The first one is a directory name; the second the file name.
+                        If pst exists, is empty, and has a filename ending in '/',
+                        we assume the previous N_SO was a directory name. */
+
+                     p = strrchr (namestring, '/');
+                     if (p && *(p + 1) == '\000')
+                       continue;               /* Simply ignore directory name SOs */
+
+                     /* Some other compilers (C++ ones in particular) emit useless
+                        SOs for non-existant .c files.  We ignore all subsequent SOs that
+                        immediately follow the first.  */
+
+                     if (!pst)
+                       pst = save_pst;
+                     continue;
+                   }
+
+                 case N_BINCL:
+                   continue;
+
+                 case N_SOL:
+                   {
+                     enum language tmp_language;
+                     /* Mark down an include file in the current psymtab */
+
+                     /* SET_NAMESTRING ();*/
+                     namestring = stabstring;
+
+                     tmp_language = deduce_language_from_filename (namestring);
+
+                     /* Only change the psymtab's language if we've learned
+                        something useful (eg. tmp_language is not language_unknown).
+                        In addition, to match what start_subfile does, never change
+                        from C++ to C.  */
+                     if (tmp_language != language_unknown
+                         && (tmp_language != language_c
+                             || psymtab_language != language_cplus))
+                       psymtab_language = tmp_language;
+
+                     /* In C++, one may expect the same filename to come round many
+                        times, when code is coming alternately from the main file
+                        and from inline functions in other files. So I check to see
+                        if this is a file we've seen before -- either the main
+                        source file, or a previously included file.
+
+                        This seems to be a lot of time to be spending on N_SOL, but
+                        things like "break c-exp.y:435" need to work (I
+                        suppose the psymtab_include_list could be hashed or put
+                        in a binary tree, if profiling shows this is a major hog).  */
+                     if (pst && STREQ (namestring, pst->filename))
+                       continue;
+                     {
+                       register int i;
+                       for (i = 0; i < includes_used; i++)
+                         if (STREQ (namestring, psymtab_include_list[i]))
+                           {
+                             i = -1;
+                             break;
+                           }
+                       if (i == -1)
+                         continue;
+                     }
+
+                     psymtab_include_list[includes_used++] = namestring;
+                     if (includes_used >= includes_allocated)
+                       {
+                         char **orig = psymtab_include_list;
+
+                         psymtab_include_list = (char **)
+                           alloca ((includes_allocated *= 2) *
+                                   sizeof (char *));
+                         memcpy ((PTR) psymtab_include_list, (PTR) orig,
+                                 includes_used * sizeof (char *));
+                       }
+                     continue;
+                   }
+                 case N_LSYM:                  /* Typedef or automatic variable. */
+                 case N_STSYM:         /* Data seg var -- static  */
+                 case N_LCSYM:         /* BSS      "  */
+                 case N_ROSYM:         /* Read-only data seg var -- static.  */
+                 case N_NBSTS:         /* Gould nobase.  */
+                 case N_NBLCS:         /* symbols.  */
+                 case N_FUN:
+                 case N_GSYM:                  /* Global (extern) variable; can be
+                                                  data or bss (sigh FIXME).  */
+
+                   /* Following may probably be ignored; I'll leave them here
+                      for now (until I do Pascal and Modula 2 extensions).  */
+
+                 case N_PC:                    /* I may or may not need this; I
+                                                  suspect not.  */
+                 case N_M2C:                   /* I suspect that I can ignore this here. */
+                 case N_SCOPE:         /* Same.   */
+
+                   /*    SET_NAMESTRING ();*/
+                   namestring = stabstring;
+                   p = (char *) strchr (namestring, ':');
+                   if (!p)
+                     continue;                 /* Not a debugging symbol.   */
+
+
+
+                   /* Main processing section for debugging symbols which
+                      the initial read through the symbol tables needs to worry
+                      about.  If we reach this point, the symbol which we are
+                      considering is definitely one we are interested in.
+                      p must also contain the (valid) index into the namestring
+                      which indicates the debugging type symbol.  */
+
+                   switch (p[1])
+                     {
+                     case 'S':
+                       sh.value += ANOFFSET (objfile->section_offsets, SECT_OFF_DATA (objfile));
+#ifdef STATIC_TRANSFORM_NAME
+                       namestring = STATIC_TRANSFORM_NAME (namestring);
+#endif
+                       add_psymbol_to_list (namestring, p - namestring,
+                                            VAR_NAMESPACE, LOC_STATIC,
+                                            &objfile->static_psymbols,
+                                            0, sh.value,
+                                            psymtab_language, objfile);
+                       continue;
+                     case 'G':
+                       sh.value += ANOFFSET (objfile->section_offsets, SECT_OFF_DATA (objfile));
+                       /* The addresses in these entries are reported to be
+                          wrong.  See the code that reads 'G's for symtabs. */
+                       add_psymbol_to_list (namestring, p - namestring,
+                                            VAR_NAMESPACE, LOC_STATIC,
+                                            &objfile->global_psymbols,
+                                            0, sh.value,
+                                            psymtab_language, objfile);
+                       continue;
+
+                     case 'T':
+                       /* When a 'T' entry is defining an anonymous enum, it
+                          may have a name which is the empty string, or a
+                          single space.  Since they're not really defining a
+                          symbol, those shouldn't go in the partial symbol
+                          table.  We do pick up the elements of such enums at
+                          'check_enum:', below.  */
+                       if (p >= namestring + 2
+                           || (p == namestring + 1
+                               && namestring[0] != ' '))
+                         {
+                           add_psymbol_to_list (namestring, p - namestring,
+                                                STRUCT_NAMESPACE, LOC_TYPEDEF,
+                                                &objfile->static_psymbols,
+                                                sh.value, 0,
+                                                psymtab_language, objfile);
+                           if (p[2] == 't')
+                             {
+                               /* Also a typedef with the same name.  */
+                               add_psymbol_to_list (namestring, p - namestring,
+                                                    VAR_NAMESPACE, LOC_TYPEDEF,
+                                                    &objfile->static_psymbols,
+                                                    sh.value, 0,
+                                                    psymtab_language, objfile);
+                               p += 1;
+                             }
+                           /* The semantics of C++ state that "struct foo { ... }"
+                              also defines a typedef for "foo".  Unfortuantely, cfront
+                              never makes the typedef when translating from C++ to C.
+                              We make the typedef here so that "ptype foo" works as
+                              expected for cfront translated code.  */
+                           else if (psymtab_language == language_cplus)
+                             {
+                               /* Also a typedef with the same name.  */
+                               add_psymbol_to_list (namestring, p - namestring,
+                                                    VAR_NAMESPACE, LOC_TYPEDEF,
+                                                    &objfile->static_psymbols,
+                                                    sh.value, 0,
+                                                    psymtab_language, objfile);
+                             }
+                         }
+                       goto check_enum;
+                     case 't':
+                       if (p != namestring)    /* a name is there, not just :T... */
+                         {
+                           add_psymbol_to_list (namestring, p - namestring,
+                                                VAR_NAMESPACE, LOC_TYPEDEF,
+                                                &objfile->static_psymbols,
+                                                sh.value, 0,
+                                                psymtab_language, objfile);
+                         }
+                     check_enum:
+                       /* If this is an enumerated type, we need to
+                          add all the enum constants to the partial symbol
+                          table.  This does not cover enums without names, e.g.
+                          "enum {a, b} c;" in C, but fortunately those are
+                          rare.  There is no way for GDB to find those from the
+                          enum type without spending too much time on it.  Thus
+                          to solve this problem, the compiler needs to put out the
+                          enum in a nameless type.  GCC2 does this.  */
+
+                       /* We are looking for something of the form
+                          <name> ":" ("t" | "T") [<number> "="] "e"
+                          {<constant> ":" <value> ","} ";".  */
+
+                       /* Skip over the colon and the 't' or 'T'.  */
+                       p += 2;
+                       /* This type may be given a number.  Also, numbers can come
+                          in pairs like (0,26).  Skip over it.  */
+                       while ((*p >= '0' && *p <= '9')
+                              || *p == '(' || *p == ',' || *p == ')'
+                              || *p == '=')
+                         p++;
+
+                       if (*p++ == 'e')
+                         {
+                           /* The aix4 compiler emits extra crud before the members.  */
+                           if (*p == '-')
+                             {
+                               /* Skip over the type (?).  */
+                               while (*p != ':')
+                                 p++;
+
+                               /* Skip over the colon.  */
+                               p++;
+                             }
+
+                           /* We have found an enumerated type.  */
+                           /* According to comments in read_enum_type
+                              a comma could end it instead of a semicolon.
+                              I don't know where that happens.
+                              Accept either.  */
+                           while (*p && *p != ';' && *p != ',')
+                             {
+                               char *q;
+
+                               /* Check for and handle cretinous dbx symbol name
+                                  continuation!  */
+                               if (*p == '\\' || (*p == '?' && p[1] == '\0'))
+                                 p = next_symbol_text (objfile);
+
+                               /* Point to the character after the name
+                                  of the enum constant.  */
+                               for (q = p; *q && *q != ':'; q++)
+                                 ;
+                               /* Note that the value doesn't matter for
+                                  enum constants in psymtabs, just in symtabs.  */
+                               add_psymbol_to_list (p, q - p,
+                                                    VAR_NAMESPACE, LOC_CONST,
+                                                    &objfile->static_psymbols, 0,
+                                                    0, psymtab_language, objfile);
+                               /* Point past the name.  */
+                               p = q;
+                               /* Skip over the value.  */
+                               while (*p && *p != ',')
+                                 p++;
+                               /* Advance past the comma.  */
+                               if (*p)
+                                 p++;
+                             }
+                         }
+                       continue;
+                     case 'c':
+                       /* Constant, e.g. from "const" in Pascal.  */
+                       add_psymbol_to_list (namestring, p - namestring,
+                                            VAR_NAMESPACE, LOC_CONST,
+                                            &objfile->static_psymbols, sh.value,
+                                            0, psymtab_language, objfile);
+                       continue;
+
+                     case 'f':
+                       if (! pst)
+                         {
+                           int name_len = p - namestring;
+                           char *name = xmalloc (name_len + 1);
+                           memcpy (name, namestring, name_len);
+                           name[name_len] = '\0';
+                           complain (&function_outside_compilation_unit, name);
+                           xfree (name);
+                         }
+                       sh.value += ANOFFSET (objfile->section_offsets, SECT_OFF_TEXT (objfile));
+                       add_psymbol_to_list (namestring, p - namestring,
+                                            VAR_NAMESPACE, LOC_BLOCK,
+                                            &objfile->static_psymbols,
+                                            0, sh.value,
+                                            psymtab_language, objfile);
+                       continue;
+
+                       /* Global functions were ignored here, but now they
+                          are put into the global psymtab like one would expect.
+                          They're also in the minimal symbol table.  */
+                     case 'F':
+                       if (! pst)
+                         {
+                           int name_len = p - namestring;
+                           char *name = xmalloc (name_len + 1);
+                           memcpy (name, namestring, name_len);
+                           name[name_len] = '\0';
+                           complain (&function_outside_compilation_unit, name);
+                           xfree (name);
+                         }
+                       sh.value += ANOFFSET (objfile->section_offsets, SECT_OFF_TEXT (objfile));
+                       add_psymbol_to_list (namestring, p - namestring,
+                                            VAR_NAMESPACE, LOC_BLOCK,
+                                            &objfile->global_psymbols,
+                                            0, sh.value,
+                                            psymtab_language, objfile);
+                       continue;
+
+                       /* Two things show up here (hopefully); static symbols of
+                          local scope (static used inside braces) or extensions
+                          of structure symbols.  We can ignore both.  */
+                     case 'V':
+                     case '(':
+                     case '0':
+                     case '1':
+                     case '2':
+                     case '3':
+                     case '4':
+                     case '5':
+                     case '6':
+                     case '7':
+                     case '8':
+                     case '9':
+                     case '-':
+                     case '#':         /* for symbol identification (used in live ranges) */
+                       /* added to support cfront stabs strings */
+                     case 'Z':         /* for definition continuations */
+                     case 'P':         /* for prototypes */
+                       continue;
+
+                     case ':':
+                       /* It is a C++ nested symbol.  We don't need to record it
+                          (I don't think); if we try to look up foo::bar::baz,
+                          then symbols for the symtab containing foo should get
+                          read in, I think.  */
+                       /* Someone says sun cc puts out symbols like
+                          /foo/baz/maclib::/usr/local/bin/maclib,
+                          which would get here with a symbol type of ':'.  */
+                       continue;
+
+                     default:
+                       /* Unexpected symbol descriptor.  The second and subsequent stabs
+                          of a continued stab can show up here.  The question is
+                          whether they ever can mimic a normal stab--it would be
+                          nice if not, since we certainly don't want to spend the
+                          time searching to the end of every string looking for
+                          a backslash.  */
+
+                       complain (&unknown_symchar_complaint, p[1]);
+
+                       /* Ignore it; perhaps it is an extension that we don't
+                          know about.  */
+                       continue;
+                     }
+
+                 case N_EXCL:
+                   continue;
+
+                 case N_ENDM:
+#ifdef SOFUN_ADDRESS_MAYBE_MISSING
+                   /* Solaris 2 end of module, finish current partial
+                      symbol table.  END_PSYMTAB will set
+                      pst->texthigh to the proper value, which is
+                      necessary if a module compiled without
+                      debugging info follows this module.  */
+                   if (pst)
+                     {
+                       pst = (struct partial_symtab *) 0;
+                       includes_used = 0;
+                       dependencies_used = 0;
+                     }
+#endif
+                   continue;
+
+                 case N_RBRAC:
+                   if (sh.value > save_pst->texthigh)
+                     save_pst->texthigh = sh.value;
+                   continue;
+                 case N_EINCL:
+                 case N_DSLINE:
+                 case N_BSLINE:
+                 case N_SSYM:                  /* Claim: Structure or union element.
+                                                  Hopefully, I can ignore this.  */
+                 case N_ENTRY:         /* Alternate entry point; can ignore. */
+                 case N_MAIN:                  /* Can definitely ignore this.   */
+                 case N_CATCH:         /* These are GNU C++ extensions */
+                 case N_EHDECL:                /* that can safely be ignored here. */
+                 case N_LENG:
+                 case N_BCOMM:
+                 case N_ECOMM:
+                 case N_ECOML:
+                 case N_FNAME:
+                 case N_SLINE:
+                 case N_RSYM:
+                 case N_PSYM:
+                 case N_LBRAC:
+                 case N_NSYMS:         /* Ultrix 4.0: symbol count */
+                 case N_DEFD:                  /* GNU Modula-2 */
+                 case N_ALIAS:         /* SunPro F77: alias name, ignore for now.  */
+
+                 case N_OBJ:                   /* useless types from Solaris */
+                 case N_OPT:
+                   /* These symbols aren't interesting; don't worry about them */
+
+                   continue;
+
+                 default:
+                   /* If we haven't found it yet, ignore it.  It's probably some
+                      new type we don't know about yet.  */
+                   complain (&unknown_symtype_complaint,
+                             local_hex_string (type_code)); /*CUR_SYMBOL_TYPE*/
+                   continue;
+                 }
+               if (stabstring
+                   && stabstring != debug_info->ss + fh->issBase + sh.iss)
+                 xfree (stabstring);
+             }
+             /* end - Handle continuation */
+           }
+       }
+      else
+       {
+         for (cur_sdx = 0; cur_sdx < fh->csym;)
+           {
+             char *name;
+             enum address_class class;
+
+             (*swap_sym_in) (cur_bfd,
+                             ((char *) debug_info->external_sym
+                              + ((fh->isymBase + cur_sdx)
+                                 * external_sym_size)),
+                             &sh);
+
+             if (ECOFF_IS_STAB (&sh))
+               {
+                 cur_sdx++;
+                 continue;
+               }
+
+             /* Non absolute static symbols go into the minimal table.  */
+             if (SC_IS_UNDEF (sh.sc) || sh.sc == scNil
+                 || (sh.index == indexNil
+                     && (sh.st != stStatic || sh.sc == scAbs)))
+               {
+                 /* FIXME, premature? */
+                 cur_sdx++;
+                 continue;
+               }
+
+             name = debug_info->ss + fh->issBase + sh.iss;
+
+             switch (sh.sc)
+               {
+               case scText:
+               case scRConst:
+                 /* The value of a stEnd symbol is the displacement from the
+                    corresponding start symbol value, do not relocate it.  */
+                 if (sh.st != stEnd)
+                   sh.value += ANOFFSET (objfile->section_offsets, SECT_OFF_TEXT (objfile));
+                 break;
+               case scData:
+               case scSData:
+               case scRData:
+               case scPData:
+               case scXData:
+                 sh.value += ANOFFSET (objfile->section_offsets, SECT_OFF_DATA (objfile));
+                 break;
+               case scBss:
+               case scSBss:
+                 sh.value += ANOFFSET (objfile->section_offsets, SECT_OFF_BSS (objfile));
+                 break;
+               }
+
+             switch (sh.st)
+               {
+                 CORE_ADDR high;
+                 CORE_ADDR procaddr;
+                 int new_sdx;
+
+               case stStaticProc:
+                 prim_record_minimal_symbol_and_info (name, sh.value,
+                                                      mst_file_text, NULL,
+                                                      SECT_OFF_TEXT (objfile), NULL,
+                                                      objfile);
+
+                 /* FALLTHROUGH */
+
+               case stProc:
+                 /* Usually there is a local and a global stProc symbol
+                    for a function. This means that the function name
+                    has already been entered into the mimimal symbol table
+                    while processing the global symbols in pass 2 above.
+                    One notable exception is the PROGRAM name from
+                    f77 compiled executables, it is only put out as
+                    local stProc symbol, and a global MAIN__ stProc symbol
+                    points to it.  It doesn't matter though, as gdb is
+                    still able to find the PROGRAM name via the partial
+                    symbol table, and the MAIN__ symbol via the minimal
+                    symbol table.  */
+                 if (sh.st == stProc)
+                   add_psymbol_to_list (name, strlen (name),
+                                        VAR_NAMESPACE, LOC_BLOCK,
+                                        &objfile->global_psymbols,
+                                   0, sh.value, psymtab_language, objfile);
+                 else
+                   add_psymbol_to_list (name, strlen (name),
+                                        VAR_NAMESPACE, LOC_BLOCK,
+                                        &objfile->static_psymbols,
+                                   0, sh.value, psymtab_language, objfile);
+
+                 /* Skip over procedure to next one. */
+                 if (sh.index >= hdr->iauxMax)
+                   {
+                     /* Should not happen, but does when cross-compiling
+                        with the MIPS compiler.  FIXME -- pull later.  */
+                     complain (&index_complaint, name);
+                     new_sdx = cur_sdx + 1;    /* Don't skip at all */
+                   }
+                 else
+                   new_sdx = AUX_GET_ISYM (fh->fBigendian,
+                                           (debug_info->external_aux
+                                            + fh->iauxBase
+                                            + sh.index));
+                 procaddr = sh.value;
+
+                 if (new_sdx <= cur_sdx)
+                   {
+                     /* This should not happen either... FIXME.  */
+                     complain (&aux_index_complaint, name);
+                     new_sdx = cur_sdx + 1;    /* Don't skip backward */
+                   }
+
+                 cur_sdx = new_sdx;
+                 (*swap_sym_in) (cur_bfd,
+                                 ((char *) debug_info->external_sym
+                                  + ((fh->isymBase + cur_sdx - 1)
+                                     * external_sym_size)),
+                                 &sh);
+                 if (sh.st != stEnd)
+                   continue;
+
+                 /* Kludge for Irix 5.2 zero fh->adr.  */
+                 if (!relocatable
+                     && (pst->textlow == 0 || procaddr < pst->textlow))
+                   pst->textlow = procaddr;
+
+                 high = procaddr + sh.value;
+                 if (high > pst->texthigh)
+                   pst->texthigh = high;
+                 continue;
+
+               case stStatic:  /* Variable */
+                 if (SC_IS_DATA (sh.sc))
+                   prim_record_minimal_symbol_and_info (name, sh.value,
+                                                        mst_file_data, NULL,
+                                                        SECT_OFF_DATA (objfile),
+                                                        NULL,
+                                                        objfile);
+                 else
+                   prim_record_minimal_symbol_and_info (name, sh.value,
+                                                        mst_file_bss, NULL,
+                                                        SECT_OFF_BSS (objfile),
+                                                        NULL,
+                                                        objfile);
+                 class = LOC_STATIC;
+                 break;
+
+               case stIndirect:        /* Irix5 forward declaration */
+                 /* Skip forward declarations from Irix5 cc */
+                 goto skip;
+
+               case stTypedef: /* Typedef */
+                 /* Skip typedefs for forward declarations and opaque
+                    structs from alpha and mips cc.  */
+                 if (sh.iss == 0 || has_opaque_xref (fh, &sh))
+                   goto skip;
+                 class = LOC_TYPEDEF;
+                 break;
+
+               case stConstant:        /* Constant decl */
+                 class = LOC_CONST;
+                 break;
+
+               case stUnion:
+               case stStruct:
+               case stEnum:
+               case stBlock:   /* { }, str, un, enum */
+                 /* Do not create a partial symbol for cc unnamed aggregates
+                    and gcc empty aggregates. */
+                 if ((sh.sc == scInfo
+                      || SC_IS_COMMON (sh.sc))
+                     && sh.iss != 0
+                     && sh.index != cur_sdx + 2)
+                   {
+                     add_psymbol_to_list (name, strlen (name),
+                                          STRUCT_NAMESPACE, LOC_TYPEDEF,
+                                          &objfile->static_psymbols,
+                                          0, (CORE_ADDR) 0,
+                                          psymtab_language, objfile);
+                   }
+                 handle_psymbol_enumerators (objfile, fh, sh.st, sh.value);
+
+                 /* Skip over the block */
+                 new_sdx = sh.index;
+                 if (new_sdx <= cur_sdx)
+                   {
+                     /* This happens with the Ultrix kernel. */
+                     complain (&block_index_complaint, name);
+                     new_sdx = cur_sdx + 1;    /* Don't skip backward */
+                   }
+                 cur_sdx = new_sdx;
+                 continue;
+
+               case stFile:    /* File headers */
+               case stLabel:   /* Labels */
+               case stEnd:     /* Ends of files */
+                 goto skip;
+
+               case stLocal:   /* Local variables */
+                 /* Normally these are skipped because we skip over
+                    all blocks we see.  However, these can occur
+                    as visible symbols in a .h file that contains code. */
+                 goto skip;
+
+               default:
+                 /* Both complaints are valid:  one gives symbol name,
+                    the other the offending symbol type.  */
+                 complain (&unknown_sym_complaint, name);
+                 complain (&unknown_st_complaint, sh.st);
+                 cur_sdx++;
+                 continue;
+               }
+             /* Use this gdb symbol */
+             add_psymbol_to_list (name, strlen (name),
+                                  VAR_NAMESPACE, class,
+                                  &objfile->static_psymbols,
+                                  0, sh.value, psymtab_language, objfile);
+           skip:
+             cur_sdx++;        /* Go to next file symbol */
+           }
+
+         /* Now do enter the external symbols. */
+         ext_ptr = &extern_tab[fdr_to_pst[f_idx].globals_offset];
+         cur_sdx = fdr_to_pst[f_idx].n_globals;
+         PST_PRIVATE (save_pst)->extern_count = cur_sdx;
+         PST_PRIVATE (save_pst)->extern_tab = ext_ptr;
+         for (; --cur_sdx >= 0; ext_ptr++)
+           {
+             enum address_class class;
+             SYMR *psh;
+             char *name;
+             CORE_ADDR svalue;
+
+             if (ext_ptr->ifd != f_idx)
+               internal_error (__FILE__, __LINE__, "failed internal consistency check");
+             psh = &ext_ptr->asym;
+
+             /* Do not add undefined symbols to the partial symbol table.  */
+             if (SC_IS_UNDEF (psh->sc) || psh->sc == scNil)
+               continue;
+
+             svalue = psh->value;
+             switch (psh->sc)
+               {
+               case scText:
+               case scRConst:
+                 svalue += ANOFFSET (objfile->section_offsets, SECT_OFF_TEXT (objfile));
+                 break;
+               case scData:
+               case scSData:
+               case scRData:
+               case scPData:
+               case scXData:
+                 svalue += ANOFFSET (objfile->section_offsets, SECT_OFF_DATA (objfile));
+                 break;
+               case scBss:
+               case scSBss:
+                 svalue += ANOFFSET (objfile->section_offsets, SECT_OFF_BSS (objfile));
+                 break;
+               }
+
+             switch (psh->st)
+               {
+               case stNil:
+                 /* These are generated for static symbols in .o files,
+                    ignore them.  */
+                 continue;
+               case stProc:
+               case stStaticProc:
+                 /* External procedure symbols have been entered
+                    into the minimal symbol table in pass 2 above.
+                    Ignore them, as parse_external will ignore them too.  */
+                 continue;
+               case stLabel:
+                 class = LOC_LABEL;
+                 break;
+               default:
+                 complain (&unknown_ext_complaint,
+                           debug_info->ssext + psh->iss);
+                 /* Fall through, pretend it's global.  */
+               case stGlobal:
+                 /* Global common symbols are resolved by the runtime loader,
+                    ignore them.  */
+                 if (SC_IS_COMMON (psh->sc))
+                   continue;
+
+                 class = LOC_STATIC;
+                 break;
+               }
+             name = debug_info->ssext + psh->iss;
+             add_psymbol_to_list (name, strlen (name),
+                                  VAR_NAMESPACE, class,
+                                  &objfile->global_psymbols,
+                                  0, svalue,
+                                  psymtab_language, objfile);
+           }
+       }
+
+      /* Link pst to FDR. end_psymtab returns NULL if the psymtab was
+         empty and put on the free list.  */
+      fdr_to_pst[f_idx].pst = end_psymtab (save_pst,
+                                       psymtab_include_list, includes_used,
+                                          -1, save_pst->texthigh,
+                      dependency_list, dependencies_used, textlow_not_set);
+      includes_used = 0;
+      dependencies_used = 0;
+
+      if (objfile->ei.entry_point >= save_pst->textlow &&
+         objfile->ei.entry_point < save_pst->texthigh)
+       {
+         objfile->ei.entry_file_lowpc = save_pst->textlow;
+         objfile->ei.entry_file_highpc = save_pst->texthigh;
+       }
+
+      /* The objfile has its functions reordered if this partial symbol
+         table overlaps any other partial symbol table.
+         We cannot assume a reordered objfile if a partial symbol table
+         is contained within another partial symbol table, as partial symbol
+         tables for include files with executable code are contained
+         within the partial symbol table for the including source file,
+         and we do not want to flag the objfile reordered for these cases.
+
+         This strategy works well for Irix-5.2 shared libraries, but we
+         might have to use a more elaborate (and slower) algorithm for
+         other cases.  */
+      save_pst = fdr_to_pst[f_idx].pst;
+      if (save_pst != NULL
+         && save_pst->textlow != 0
+         && !(objfile->flags & OBJF_REORDERED))
+       {
+         ALL_OBJFILE_PSYMTABS (objfile, pst)
+         {
+           if (save_pst != pst
+               && save_pst->textlow >= pst->textlow
+               && save_pst->textlow < pst->texthigh
+               && save_pst->texthigh > pst->texthigh)
+             {
+               objfile->flags |= OBJF_REORDERED;
+               break;
+             }
+         }
+       }
+    }
+
+  /* Now scan the FDRs for dependencies */
+  for (f_idx = 0; f_idx < hdr->ifdMax; f_idx++)
+    {
+      fh = f_idx + debug_info->fdr;
+      pst = fdr_to_pst[f_idx].pst;
+
+      if (pst == (struct partial_symtab *) NULL)
+       continue;
+
+      /* This should catch stabs-in-ecoff. */
+      if (fh->crfd <= 1)
+       continue;
+
+      /* Skip the first file indirect entry as it is a self dependency
+         for source files or a reverse .h -> .c dependency for header files.  */
+      pst->number_of_dependencies = 0;
+      pst->dependencies =
+       ((struct partial_symtab **)
+        obstack_alloc (&objfile->psymbol_obstack,
+                       ((fh->crfd - 1)
+                        * sizeof (struct partial_symtab *))));
+      for (s_idx = 1; s_idx < fh->crfd; s_idx++)
+       {
+         RFDT rh;
+
+         (*swap_rfd_in) (cur_bfd,
+                         ((char *) debug_info->external_rfd
+                          + (fh->rfdBase + s_idx) * external_rfd_size),
+                         &rh);
+         if (rh < 0 || rh >= hdr->ifdMax)
+           {
+             complain (&bad_file_number_complaint, rh);
+             continue;
+           }
+
+         /* Skip self dependencies of header files.  */
+         if (rh == f_idx)
+           continue;
+
+         /* Do not add to dependeny list if psymtab was empty.  */
+         if (fdr_to_pst[rh].pst == (struct partial_symtab *) NULL)
+           continue;
+         pst->dependencies[pst->number_of_dependencies++] = fdr_to_pst[rh].pst;
+       }
+    }
+
+  /* Remove the dummy psymtab created for -O3 images above, if it is
+     still empty, to enable the detection of stripped executables.  */
+  if (objfile->psymtabs->next == NULL
+      && objfile->psymtabs->number_of_dependencies == 0
+      && objfile->psymtabs->n_global_syms == 0
+      && objfile->psymtabs->n_static_syms == 0)
+    objfile->psymtabs = NULL;
+  do_cleanups (old_chain);
+}
+
+/* If the current psymbol has an enumerated type, we need to add
+   all the the enum constants to the partial symbol table.  */
+
+static void
+handle_psymbol_enumerators (struct objfile *objfile, FDR *fh, int stype,
+                           CORE_ADDR svalue)
+{
+  const bfd_size_type external_sym_size = debug_swap->external_sym_size;
+  void (*const swap_sym_in) (bfd *, void *, SYMR *) = debug_swap->swap_sym_in;
+  char *ext_sym = ((char *) debug_info->external_sym
+                  + ((fh->isymBase + cur_sdx + 1) * external_sym_size));
+  SYMR sh;
+  TIR tir;
+
+  switch (stype)
+    {
+    case stEnum:
+      break;
+
+    case stBlock:
+      /* It is an enumerated type if the next symbol entry is a stMember
+         and its auxiliary index is indexNil or its auxiliary entry
+         is a plain btNil or btVoid.
+         Alpha cc -migrate enums are recognized by a zero index and
+         a zero symbol value.
+         DU 4.0 cc enums are recognized by a member type of btEnum without
+         qualifiers and a zero symbol value.  */
+      (*swap_sym_in) (cur_bfd, ext_sym, &sh);
+      if (sh.st != stMember)
+       return;
+
+      if (sh.index == indexNil
+         || (sh.index == 0 && svalue == 0))
+       break;
+      (*debug_swap->swap_tir_in) (fh->fBigendian,
+                                 &(debug_info->external_aux
+                                   + fh->iauxBase + sh.index)->a_ti,
+                                 &tir);
+      if ((tir.bt != btNil
+          && tir.bt != btVoid
+          && (tir.bt != btEnum || svalue != 0))
+         || tir.tq0 != tqNil)
+       return;
+      break;
+
+    default:
+      return;
+    }
+
+  for (;;)
+    {
+      char *name;
+
+      (*swap_sym_in) (cur_bfd, ext_sym, &sh);
+      if (sh.st != stMember)
+       break;
+      name = debug_info->ss + cur_fdr->issBase + sh.iss;
+
+      /* Note that the value doesn't matter for enum constants
+         in psymtabs, just in symtabs.  */
+      add_psymbol_to_list (name, strlen (name),
+                          VAR_NAMESPACE, LOC_CONST,
+                          &objfile->static_psymbols, 0,
+                          (CORE_ADDR) 0, psymtab_language, objfile);
+      ext_sym += external_sym_size;
+    }
+}
+
+/* Get the next symbol.  OBJFILE is unused. */
+
+static char *
+mdebug_next_symbol_text (struct objfile *objfile)
+{
+  SYMR sh;
+
+  cur_sdx++;
+  (*debug_swap->swap_sym_in) (cur_bfd,
+                             ((char *) debug_info->external_sym
+                              + ((cur_fdr->isymBase + cur_sdx)
+                                 * debug_swap->external_sym_size)),
+                             &sh);
+  return debug_info->ss + cur_fdr->issBase + sh.iss;
+}
+
+/* Ancillary function to psymtab_to_symtab().  Does all the work
+   for turning the partial symtab PST into a symtab, recurring
+   first on all dependent psymtabs.  The argument FILENAME is
+   only passed so we can see in debug stack traces what file
+   is being read.
+
+   This function has a split personality, based on whether the
+   symbol table contains ordinary ecoff symbols, or stabs-in-ecoff.
+   The flow of control and even the memory allocation differs.  FIXME.  */
+
+static void
+psymtab_to_symtab_1 (struct partial_symtab *pst, char *filename)
+{
+  bfd_size_type external_sym_size;
+  bfd_size_type external_pdr_size;
+  void (*swap_sym_in) (bfd *, void *, SYMR *);
+  void (*swap_pdr_in) (bfd *, void *, PDR *);
+  int i;
+  struct symtab *st = NULL;
+  FDR *fh;
+  struct linetable *lines;
+  CORE_ADDR lowest_pdr_addr = 0;
+  int last_symtab_ended = 0;
+
+  if (pst->readin)
+    return;
+  pst->readin = 1;
+
+  /* Read in all partial symbtabs on which this one is dependent.
+     NOTE that we do have circular dependencies, sigh.  We solved
+     that by setting pst->readin before this point.  */
+
+  for (i = 0; i < pst->number_of_dependencies; i++)
+    if (!pst->dependencies[i]->readin)
+      {
+       /* Inform about additional files to be read in.  */
+       if (info_verbose)
+         {
+           fputs_filtered (" ", gdb_stdout);
+           wrap_here ("");
+           fputs_filtered ("and ", gdb_stdout);
+           wrap_here ("");
+           printf_filtered ("%s...",
+                            pst->dependencies[i]->filename);
+           wrap_here ("");     /* Flush output */
+           gdb_flush (gdb_stdout);
+         }
+       /* We only pass the filename for debug purposes */
+       psymtab_to_symtab_1 (pst->dependencies[i],
+                            pst->dependencies[i]->filename);
+      }
+
+  /* Do nothing if this is a dummy psymtab.  */
+
+  if (pst->n_global_syms == 0 && pst->n_static_syms == 0
+      && pst->textlow == 0 && pst->texthigh == 0)
+    return;
+
+  /* Now read the symbols for this symtab */
+
+  cur_bfd = CUR_BFD (pst);
+  debug_swap = DEBUG_SWAP (pst);
+  debug_info = DEBUG_INFO (pst);
+  pending_list = PENDING_LIST (pst);
+  external_sym_size = debug_swap->external_sym_size;
+  external_pdr_size = debug_swap->external_pdr_size;
+  swap_sym_in = debug_swap->swap_sym_in;
+  swap_pdr_in = debug_swap->swap_pdr_in;
+  current_objfile = pst->objfile;
+  cur_fd = FDR_IDX (pst);
+  fh = ((cur_fd == -1)
+       ? (FDR *) NULL
+       : debug_info->fdr + cur_fd);
+  cur_fdr = fh;
+
+  /* See comment in parse_partial_symbols about the @stabs sentinel. */
+  processing_gcc_compilation = 0;
+  if (fh != (FDR *) NULL && fh->csym >= 2)
+    {
+      SYMR sh;
+
+      (*swap_sym_in) (cur_bfd,
+                     ((char *) debug_info->external_sym
+                      + (fh->isymBase + 1) * external_sym_size),
+                     &sh);
+      if (STREQ (debug_info->ss + fh->issBase + sh.iss,
+                stabs_symbol))
+       {
+         /* We indicate that this is a GCC compilation so that certain
+            features will be enabled in stabsread/dbxread.  */
+         processing_gcc_compilation = 2;
+       }
+    }
+
+  if (processing_gcc_compilation != 0)
+    {
+
+      /* This symbol table contains stabs-in-ecoff entries.  */
+
+      /* Parse local symbols first */
+
+      if (fh->csym <= 2)       /* FIXME, this blows psymtab->symtab ptr */
+       {
+         current_objfile = NULL;
+         return;
+       }
+      for (cur_sdx = 2; cur_sdx < fh->csym; cur_sdx++)
+       {
+         SYMR sh;
+         char *name;
+         CORE_ADDR valu;
+
+         (*swap_sym_in) (cur_bfd,
+                         (((char *) debug_info->external_sym)
+                          + (fh->isymBase + cur_sdx) * external_sym_size),
+                         &sh);
+         name = debug_info->ss + fh->issBase + sh.iss;
+         valu = sh.value;
+         /* XXX This is a hack.  It will go away!  */
+         if (ECOFF_IS_STAB (&sh) || (name[0] == '#'))
+           {
+             int type_code = ECOFF_UNMARK_STAB (sh.index);
+
+             /* We should never get non N_STAB symbols here, but they
+                should be harmless, so keep process_one_symbol from
+                complaining about them.  */
+             if (type_code & N_STAB)
+               {
+                 /* If we found a trailing N_SO with no name, process
+                     it here instead of in process_one_symbol, so we
+                     can keep a handle to its symtab.  The symtab
+                     would otherwise be ended twice, once in
+                     process_one_symbol, and once after this loop. */
+                 if (type_code == N_SO
+                     && last_source_file
+                     && previous_stab_code != (unsigned char) N_SO
+                     && *name == '\000')
+                   {
+                     valu += ANOFFSET (pst->section_offsets,
+                                       SECT_OFF_TEXT (pst->objfile));
+                     previous_stab_code = N_SO;
+                     st = end_symtab (valu, pst->objfile,
+                                      SECT_OFF_TEXT (pst->objfile));
+                     end_stabs ();
+                     last_symtab_ended = 1;
+                   }
+                 else
+                   {
+                     last_symtab_ended = 0;
+                     process_one_symbol (type_code, 0, valu, name,
+                                         pst->section_offsets, pst->objfile);
+                   }
+               }
+             /* Similarly a hack.  */
+             else if (name[0] == '#')
+               {
+                 process_one_symbol (N_SLINE, 0, valu, name,
+                                     pst->section_offsets, pst->objfile);
+               }
+             if (type_code == N_FUN)
+               {
+                 /* Make up special symbol to contain
+                    procedure specific info */
+                 struct mips_extra_func_info *e =
+                 ((struct mips_extra_func_info *)
+                  obstack_alloc (&current_objfile->symbol_obstack,
+                                 sizeof (struct mips_extra_func_info)));
+                 struct symbol *s = new_symbol (MIPS_EFI_SYMBOL_NAME);
+
+                 memset (e, 0, sizeof (struct mips_extra_func_info));
+                 SYMBOL_NAMESPACE (s) = LABEL_NAMESPACE;
+                 SYMBOL_CLASS (s) = LOC_CONST;
+                 SYMBOL_TYPE (s) = mdebug_type_void;
+                 SYMBOL_VALUE (s) = (long) e;
+                 e->pdr.framereg = -1;
+                 add_symbol_to_list (s, &local_symbols);
+               }
+           }
+         else if (sh.st == stLabel)
+           {
+             if (sh.index == indexNil)
+               {
+                 /* This is what the gcc2_compiled and __gnu_compiled_*
+                    show up as.  So don't complain.  */
+                 ;
+               }
+             else
+               {
+                 /* Handle encoded stab line number. */
+                 valu += ANOFFSET (pst->section_offsets, SECT_OFF_TEXT (pst->objfile));
+                 record_line (current_subfile, sh.index, valu);
+               }
+           }
+         else if (sh.st == stProc || sh.st == stStaticProc
+                  || sh.st == stStatic || sh.st == stEnd)
+           /* These are generated by gcc-2.x, do not complain */
+           ;
+         else
+           complain (&stab_unknown_complaint, name);
+       }
+
+      if (! last_symtab_ended)
+       {
+         st = end_symtab (pst->texthigh, pst->objfile, SECT_OFF_TEXT (pst->objfile));
+         end_stabs ();
+       }
+
+      /* Sort the symbol table now, we are done adding symbols to it.
+         We must do this before parse_procedure calls lookup_symbol.  */
+      sort_symtab_syms (st);
+
+      /* There used to be a call to sort_blocks here, but this should not
+         be necessary for stabs symtabs.  And as sort_blocks modifies the
+         start address of the GLOBAL_BLOCK to the FIRST_LOCAL_BLOCK,
+         it did the wrong thing if the first procedure in a file was
+         generated via asm statements.  */
+
+      /* Fill in procedure info next.  */
+      if (fh->cpd > 0)
+       {
+         PDR *pr_block;
+         struct cleanup *old_chain;
+         char *pdr_ptr;
+         char *pdr_end;
+         PDR *pdr_in;
+         PDR *pdr_in_end;
+
+         pr_block = (PDR *) xmalloc (fh->cpd * sizeof (PDR));
+         old_chain = make_cleanup (xfree, pr_block);
+
+         pdr_ptr = ((char *) debug_info->external_pdr
+                    + fh->ipdFirst * external_pdr_size);
+         pdr_end = pdr_ptr + fh->cpd * external_pdr_size;
+         pdr_in = pr_block;
+         for (;
+              pdr_ptr < pdr_end;
+              pdr_ptr += external_pdr_size, pdr_in++)
+           {
+             (*swap_pdr_in) (cur_bfd, pdr_ptr, pdr_in);
+
+             /* Determine lowest PDR address, the PDRs are not always
+                sorted.  */
+             if (pdr_in == pr_block)
+               lowest_pdr_addr = pdr_in->adr;
+             else if (pdr_in->adr < lowest_pdr_addr)
+               lowest_pdr_addr = pdr_in->adr;
+           }
+
+         pdr_in = pr_block;
+         pdr_in_end = pdr_in + fh->cpd;
+         for (; pdr_in < pdr_in_end; pdr_in++)
+           parse_procedure (pdr_in, st, pst);
+
+         do_cleanups (old_chain);
+       }
+    }
+  else
+    {
+      /* This symbol table contains ordinary ecoff entries.  */
+
+      int f_max;
+      int maxlines;
+      EXTR *ext_ptr;
+
+      /* How many symbols will we need */
+      /* FIXME, this does not count enum values. */
+      f_max = pst->n_global_syms + pst->n_static_syms;
+      if (fh == 0)
+       {
+         maxlines = 0;
+         st = new_symtab ("unknown", f_max, 0, pst->objfile);
+       }
+      else
+       {
+         f_max += fh->csym + fh->cpd;
+         maxlines = 2 * fh->cline;
+         st = new_symtab (pst->filename, 2 * f_max, maxlines, pst->objfile);
+
+         /* The proper language was already determined when building
+            the psymtab, use it.  */
+         st->language = PST_PRIVATE (pst)->pst_language;
+       }
+
+      psymtab_language = st->language;
+
+      lines = LINETABLE (st);
+
+      /* Get a new lexical context */
+
+      push_parse_stack ();
+      top_stack->cur_st = st;
+      top_stack->cur_block = BLOCKVECTOR_BLOCK (BLOCKVECTOR (st),
+                                               STATIC_BLOCK);
+      BLOCK_START (top_stack->cur_block) = pst->textlow;
+      BLOCK_END (top_stack->cur_block) = 0;
+      top_stack->blocktype = stFile;
+      top_stack->maxsyms = 2 * f_max;
+      top_stack->cur_type = 0;
+      top_stack->procadr = 0;
+      top_stack->numargs = 0;
+      found_ecoff_debugging_info = 0;
+
+      if (fh)
+       {
+         char *sym_ptr;
+         char *sym_end;
+
+         /* Parse local symbols first */
+         sym_ptr = ((char *) debug_info->external_sym
+                    + fh->isymBase * external_sym_size);
+         sym_end = sym_ptr + fh->csym * external_sym_size;
+         while (sym_ptr < sym_end)
+           {
+             SYMR sh;
+             int c;
+
+             (*swap_sym_in) (cur_bfd, sym_ptr, &sh);
+             c = parse_symbol (&sh,
+                               debug_info->external_aux + fh->iauxBase,
+                               sym_ptr, fh->fBigendian, pst->section_offsets, pst->objfile);
+             sym_ptr += c * external_sym_size;
+           }
+
+         /* Linenumbers.  At the end, check if we can save memory.
+            parse_lines has to look ahead an arbitrary number of PDR
+            structures, so we swap them all first.  */
+         if (fh->cpd > 0)
+           {
+             PDR *pr_block;
+             struct cleanup *old_chain;
+             char *pdr_ptr;
+             char *pdr_end;
+             PDR *pdr_in;
+             PDR *pdr_in_end;
+
+             pr_block = (PDR *) xmalloc (fh->cpd * sizeof (PDR));
+
+             old_chain = make_cleanup (xfree, pr_block);
+
+             pdr_ptr = ((char *) debug_info->external_pdr
+                        + fh->ipdFirst * external_pdr_size);
+             pdr_end = pdr_ptr + fh->cpd * external_pdr_size;
+             pdr_in = pr_block;
+             for (;
+                  pdr_ptr < pdr_end;
+                  pdr_ptr += external_pdr_size, pdr_in++)
+               {
+                 (*swap_pdr_in) (cur_bfd, pdr_ptr, pdr_in);
+
+                 /* Determine lowest PDR address, the PDRs are not always
+                    sorted.  */
+                 if (pdr_in == pr_block)
+                   lowest_pdr_addr = pdr_in->adr;
+                 else if (pdr_in->adr < lowest_pdr_addr)
+                   lowest_pdr_addr = pdr_in->adr;
+               }
+
+             parse_lines (fh, pr_block, lines, maxlines, pst, lowest_pdr_addr);
+             if (lines->nitems < fh->cline)
+               lines = shrink_linetable (lines);
+
+             /* Fill in procedure info next.  */
+             pdr_in = pr_block;
+             pdr_in_end = pdr_in + fh->cpd;
+             for (; pdr_in < pdr_in_end; pdr_in++)
+               parse_procedure (pdr_in, 0, pst);
+
+             do_cleanups (old_chain);
+           }
+       }
+
+      LINETABLE (st) = lines;
+
+      /* .. and our share of externals.
+         XXX use the global list to speed up things here. how?
+         FIXME, Maybe quit once we have found the right number of ext's? */
+      top_stack->cur_st = st;
+      top_stack->cur_block = BLOCKVECTOR_BLOCK (BLOCKVECTOR (top_stack->cur_st),
+                                               GLOBAL_BLOCK);
+      top_stack->blocktype = stFile;
+      top_stack->maxsyms
+       = (debug_info->symbolic_header.isymMax
+          + debug_info->symbolic_header.ipdMax
+          + debug_info->symbolic_header.iextMax);
+
+      ext_ptr = PST_PRIVATE (pst)->extern_tab;
+      for (i = PST_PRIVATE (pst)->extern_count; --i >= 0; ext_ptr++)
+       parse_external (ext_ptr, fh->fBigendian, pst->section_offsets, pst->objfile);
+
+      /* If there are undefined symbols, tell the user.
+         The alpha has an undefined symbol for every symbol that is
+         from a shared library, so tell the user only if verbose is on.  */
+      if (info_verbose && n_undef_symbols)
+       {
+         printf_filtered ("File %s contains %d unresolved references:",
+                          st->filename, n_undef_symbols);
+         printf_filtered ("\n\t%4d variables\n\t%4d procedures\n\t%4d labels\n",
+                          n_undef_vars, n_undef_procs, n_undef_labels);
+         n_undef_symbols = n_undef_labels = n_undef_vars = n_undef_procs = 0;
+
+       }
+      pop_parse_stack ();
+
+      st->primary = 1;
+
+      /* Sort the symbol table now, we are done adding symbols to it. */
+      sort_symtab_syms (st);
+
+      sort_blocks (st);
+    }
+
+  /* Now link the psymtab and the symtab.  */
+  pst->symtab = st;
+
+  current_objfile = NULL;
+}
+\f
+/* Ancillary parsing procedures. */
+
+/* Return 1 if the symbol pointed to by SH has a cross reference
+   to an opaque aggregate type, else 0.  */
+
+static int
+has_opaque_xref (FDR *fh, SYMR *sh)
+{
+  TIR tir;
+  union aux_ext *ax;
+  RNDXR rn[1];
+  unsigned int rf;
+
+  if (sh->index == indexNil)
+    return 0;
+
+  ax = debug_info->external_aux + fh->iauxBase + sh->index;
+  (*debug_swap->swap_tir_in) (fh->fBigendian, &ax->a_ti, &tir);
+  if (tir.bt != btStruct && tir.bt != btUnion && tir.bt != btEnum)
+    return 0;
+
+  ax++;
+  (*debug_swap->swap_rndx_in) (fh->fBigendian, &ax->a_rndx, rn);
+  if (rn->rfd == 0xfff)
+    rf = AUX_GET_ISYM (fh->fBigendian, ax + 1);
+  else
+    rf = rn->rfd;
+  if (rf != -1)
+    return 0;
+  return 1;
+}
+
+/* Lookup the type at relative index RN.  Return it in TPP
+   if found and in any event come up with its name PNAME.
+   BIGEND says whether aux symbols are big-endian or not (from fh->fBigendian).
+   Return value says how many aux symbols we ate. */
+
+static int
+cross_ref (int fd, union aux_ext *ax, struct type **tpp, enum type_code type_code,     /* Use to alloc new type if none is found. */
+          char **pname, int bigend, char *sym_name)
+{
+  RNDXR rn[1];
+  unsigned int rf;
+  int result = 1;
+  FDR *fh;
+  char *esh;
+  SYMR sh;
+  int xref_fd;
+  struct mdebug_pending *pend;
+
+  *tpp = (struct type *) NULL;
+
+  (*debug_swap->swap_rndx_in) (bigend, &ax->a_rndx, rn);
+
+  /* Escape index means 'the next one' */
+  if (rn->rfd == 0xfff)
+    {
+      result++;
+      rf = AUX_GET_ISYM (bigend, ax + 1);
+    }
+  else
+    {
+      rf = rn->rfd;
+    }
+
+  /* mips cc uses a rf of -1 for opaque struct definitions.
+     Set TYPE_FLAG_STUB for these types so that check_typedef will
+     resolve them if the struct gets defined in another compilation unit.  */
+  if (rf == -1)
+    {
+      *pname = "<undefined>";
+      *tpp = init_type (type_code, 0, TYPE_FLAG_STUB, (char *) NULL, current_objfile);
+      return result;
+    }
+
+  /* mips cc uses an escaped rn->index of 0 for struct return types
+     of procedures that were compiled without -g. These will always remain
+     undefined.  */
+  if (rn->rfd == 0xfff && rn->index == 0)
+    {
+      *pname = "<undefined>";
+      return result;
+    }
+
+  /* Find the relative file descriptor and the symbol in it.  */
+  fh = get_rfd (fd, rf);
+  xref_fd = fh - debug_info->fdr;
+
+  if (rn->index >= fh->csym)
+    {
+      /* File indirect entry is corrupt.  */
+      *pname = "<illegal>";
+      complain (&bad_rfd_entry_complaint,
+               sym_name, xref_fd, rn->index);
+      return result;
+    }
+
+  /* If we have processed this symbol then we left a forwarding
+     pointer to the type in the pending list.  If not, we`ll put
+     it in a list of pending types, to be processed later when
+     the file will be.  In any event, we collect the name for the
+     type here.  */
+
+  esh = ((char *) debug_info->external_sym
+        + ((fh->isymBase + rn->index)
+           * debug_swap->external_sym_size));
+  (*debug_swap->swap_sym_in) (cur_bfd, esh, &sh);
+
+  /* Make sure that this type of cross reference can be handled.  */
+  if ((sh.sc != scInfo
+       || (sh.st != stBlock && sh.st != stTypedef && sh.st != stIndirect
+          && sh.st != stStruct && sh.st != stUnion
+          && sh.st != stEnum))
+      && (sh.st != stBlock || !SC_IS_COMMON (sh.sc)))
+    {
+      /* File indirect entry is corrupt.  */
+      *pname = "<illegal>";
+      complain (&bad_rfd_entry_complaint,
+               sym_name, xref_fd, rn->index);
+      return result;
+    }
+
+  *pname = debug_info->ss + fh->issBase + sh.iss;
+
+  pend = is_pending_symbol (fh, esh);
+  if (pend)
+    *tpp = pend->t;
+  else
+    {
+      /* We have not yet seen this type.  */
+
+      if ((sh.iss == 0 && sh.st == stTypedef) || sh.st == stIndirect)
+       {
+         TIR tir;
+
+         /* alpha cc puts out a stTypedef with a sh.iss of zero for
+            two cases:
+            a) forward declarations of structs/unions/enums which are not
+            defined in this compilation unit.
+            For these the type will be void. This is a bad design decision
+            as cross referencing across compilation units is impossible
+            due to the missing name.
+            b) forward declarations of structs/unions/enums/typedefs which
+            are defined later in this file or in another file in the same
+            compilation unit. Irix5 cc uses a stIndirect symbol for this.
+            Simply cross reference those again to get the true type.
+            The forward references are not entered in the pending list and
+            in the symbol table.  */
+
+         (*debug_swap->swap_tir_in) (bigend,
+                                     &(debug_info->external_aux
+                                       + fh->iauxBase + sh.index)->a_ti,
+                                     &tir);
+         if (tir.tq0 != tqNil)
+           complain (&illegal_forward_tq0_complaint, sym_name);
+         switch (tir.bt)
+           {
+           case btVoid:
+             *tpp = init_type (type_code, 0, 0, (char *) NULL,
+                               current_objfile);
+             *pname = "<undefined>";
+             break;
+
+           case btStruct:
+           case btUnion:
+           case btEnum:
+             cross_ref (xref_fd,
+                        (debug_info->external_aux
+                         + fh->iauxBase + sh.index + 1),
+                        tpp, type_code, pname,
+                        fh->fBigendian, sym_name);
+             break;
+
+           case btTypedef:
+             /* Follow a forward typedef. This might recursively
+                call cross_ref till we get a non typedef'ed type.
+                FIXME: This is not correct behaviour, but gdb currently
+                cannot handle typedefs without type copying. Type
+                copying is impossible as we might have mutual forward
+                references between two files and the copied type would not
+                get filled in when we later parse its definition.  */
+             *tpp = parse_type (xref_fd,
+                                debug_info->external_aux + fh->iauxBase,
+                                sh.index,
+                                (int *) NULL,
+                                fh->fBigendian,
+                                debug_info->ss + fh->issBase + sh.iss);
+             add_pending (fh, esh, *tpp);
+             break;
+
+           default:
+             complain (&illegal_forward_bt_complaint, tir.bt, sym_name);
+             *tpp = init_type (type_code, 0, 0, (char *) NULL,
+                               current_objfile);
+             break;
+           }
+         return result;
+       }
+      else if (sh.st == stTypedef)
+       {
+         /* Parse the type for a normal typedef. This might recursively call
+            cross_ref till we get a non typedef'ed type.
+            FIXME: This is not correct behaviour, but gdb currently
+            cannot handle typedefs without type copying. But type copying is
+            impossible as we might have mutual forward references between
+            two files and the copied type would not get filled in when
+            we later parse its definition.   */
+         *tpp = parse_type (xref_fd,
+                            debug_info->external_aux + fh->iauxBase,
+                            sh.index,
+                            (int *) NULL,
+                            fh->fBigendian,
+                            debug_info->ss + fh->issBase + sh.iss);
+       }
+      else
+       {
+         /* Cross reference to a struct/union/enum which is defined
+            in another file in the same compilation unit but that file
+            has not been parsed yet.
+            Initialize the type only, it will be filled in when
+            it's definition is parsed.  */
+         *tpp = init_type (type_code, 0, 0, (char *) NULL, current_objfile);
+       }
+      add_pending (fh, esh, *tpp);
+    }
+
+  /* We used one auxent normally, two if we got a "next one" rf. */
+  return result;
+}
+
+
+/* Quick&dirty lookup procedure, to avoid the MI ones that require
+   keeping the symtab sorted */
+
+static struct symbol *
+mylookup_symbol (char *name, register struct block *block,
+                namespace_enum namespace, enum address_class class)
+{
+  int i, inc;
+  struct symbol *sym;
+
+  inc = name[0];
+  ALL_BLOCK_SYMBOLS (block, i, sym)
+    {
+      if (SYMBOL_NAME (sym)[0] == inc
+         && SYMBOL_NAMESPACE (sym) == namespace
+         && SYMBOL_CLASS (sym) == class
+         && strcmp (SYMBOL_NAME (sym), name) == 0)
+       return sym;
+    }
+
+  block = BLOCK_SUPERBLOCK (block);
+  if (block)
+    return mylookup_symbol (name, block, namespace, class);
+  return 0;
+}
+
+
+/* Add a new symbol S to a block B.
+   Infrequently, we will need to reallocate the block to make it bigger.
+   We only detect this case when adding to top_stack->cur_block, since
+   that's the only time we know how big the block is.  FIXME.  */
+
+static void
+add_symbol (struct symbol *s, struct block *b)
+{
+  int nsyms = BLOCK_NSYMS (b)++;
+  struct block *origb;
+  struct parse_stack *stackp;
+
+  if (b == top_stack->cur_block &&
+      nsyms >= top_stack->maxsyms)
+    {
+      complain (&block_overflow_complaint, SYMBOL_NAME (s));
+      /* In this case shrink_block is actually grow_block, since
+         BLOCK_NSYMS(b) is larger than its current size.  */
+      origb = b;
+      b = shrink_block (top_stack->cur_block, top_stack->cur_st);
+
+      /* Now run through the stack replacing pointers to the
+         original block.  shrink_block has already done this
+         for the blockvector and BLOCK_FUNCTION.  */
+      for (stackp = top_stack; stackp; stackp = stackp->next)
+       {
+         if (stackp->cur_block == origb)
+           {
+             stackp->cur_block = b;
+             stackp->maxsyms = BLOCK_NSYMS (b);
+           }
+       }
+    }
+  BLOCK_SYM (b, nsyms) = s;
+}
+
+/* Add a new block B to a symtab S */
+
+static void
+add_block (struct block *b, struct symtab *s)
+{
+  struct blockvector *bv = BLOCKVECTOR (s);
+
+  bv = (struct blockvector *) xrealloc ((void *) bv,
+                                       (sizeof (struct blockvector)
+                                        + BLOCKVECTOR_NBLOCKS (bv)
+                                        * sizeof (bv->block)));
+  if (bv != BLOCKVECTOR (s))
+    BLOCKVECTOR (s) = bv;
+
+  BLOCKVECTOR_BLOCK (bv, BLOCKVECTOR_NBLOCKS (bv)++) = b;
+}
+
+/* Add a new linenumber entry (LINENO,ADR) to a linevector LT.
+   MIPS' linenumber encoding might need more than one byte
+   to describe it, LAST is used to detect these continuation lines.
+
+   Combining lines with the same line number seems like a bad idea.
+   E.g: There could be a line number entry with the same line number after the
+   prologue and GDB should not ignore it (this is a better way to find
+   a prologue than mips_skip_prologue).
+   But due to the compressed line table format there are line number entries
+   for the same line which are needed to bridge the gap to the next
+   line number entry. These entries have a bogus address info with them
+   and we are unable to tell them from intended duplicate line number
+   entries.
+   This is another reason why -ggdb debugging format is preferable.  */
+
+static int
+add_line (struct linetable *lt, int lineno, CORE_ADDR adr, int last)
+{
+  /* DEC c89 sometimes produces zero linenos which confuse gdb.
+     Change them to something sensible. */
+  if (lineno == 0)
+    lineno = 1;
+  if (last == 0)
+    last = -2;                 /* make sure we record first line */
+
+  if (last == lineno)          /* skip continuation lines */
+    return lineno;
+
+  lt->item[lt->nitems].line = lineno;
+  lt->item[lt->nitems++].pc = adr << 2;
+  return lineno;
+}
+\f
+/* Sorting and reordering procedures */
+
+/* Blocks with a smaller low bound should come first */
+
+static int
+compare_blocks (const void *arg1, const void *arg2)
+{
+  register int addr_diff;
+  struct block **b1 = (struct block **) arg1;
+  struct block **b2 = (struct block **) arg2;
+
+  addr_diff = (BLOCK_START ((*b1))) - (BLOCK_START ((*b2)));
+  if (addr_diff == 0)
+    return (BLOCK_END ((*b2))) - (BLOCK_END ((*b1)));
+  return addr_diff;
+}
+
+/* Sort the blocks of a symtab S.
+   Reorder the blocks in the blockvector by code-address,
+   as required by some MI search routines */
+
+static void
+sort_blocks (struct symtab *s)
+{
+  struct blockvector *bv = BLOCKVECTOR (s);
+
+  if (BLOCKVECTOR_NBLOCKS (bv) <= 2)
+    {
+      /* Cosmetic */
+      if (BLOCK_END (BLOCKVECTOR_BLOCK (bv, GLOBAL_BLOCK)) == 0)
+       BLOCK_START (BLOCKVECTOR_BLOCK (bv, GLOBAL_BLOCK)) = 0;
+      if (BLOCK_END (BLOCKVECTOR_BLOCK (bv, STATIC_BLOCK)) == 0)
+       BLOCK_START (BLOCKVECTOR_BLOCK (bv, STATIC_BLOCK)) = 0;
+      return;
+    }
+  /*
+   * This is very unfortunate: normally all functions are compiled in
+   * the order they are found, but if the file is compiled -O3 things
+   * are very different.  It would be nice to find a reliable test
+   * to detect -O3 images in advance.
+   */
+  if (BLOCKVECTOR_NBLOCKS (bv) > 3)
+    qsort (&BLOCKVECTOR_BLOCK (bv, FIRST_LOCAL_BLOCK),
+          BLOCKVECTOR_NBLOCKS (bv) - FIRST_LOCAL_BLOCK,
+          sizeof (struct block *),
+          compare_blocks);
+
+  {
+    register CORE_ADDR high = 0;
+    register int i, j = BLOCKVECTOR_NBLOCKS (bv);
+
+    for (i = FIRST_LOCAL_BLOCK; i < j; i++)
+      if (high < BLOCK_END (BLOCKVECTOR_BLOCK (bv, i)))
+       high = BLOCK_END (BLOCKVECTOR_BLOCK (bv, i));
+    BLOCK_END (BLOCKVECTOR_BLOCK (bv, GLOBAL_BLOCK)) = high;
+  }
+
+  BLOCK_START (BLOCKVECTOR_BLOCK (bv, GLOBAL_BLOCK)) =
+    BLOCK_START (BLOCKVECTOR_BLOCK (bv, FIRST_LOCAL_BLOCK));
+
+  BLOCK_START (BLOCKVECTOR_BLOCK (bv, STATIC_BLOCK)) =
+    BLOCK_START (BLOCKVECTOR_BLOCK (bv, GLOBAL_BLOCK));
+  BLOCK_END (BLOCKVECTOR_BLOCK (bv, STATIC_BLOCK)) =
+    BLOCK_END (BLOCKVECTOR_BLOCK (bv, GLOBAL_BLOCK));
+}
+\f
+
+/* Constructor/restructor/destructor procedures */
+
+/* Allocate a new symtab for NAME.  Needs an estimate of how many symbols
+   MAXSYMS and linenumbers MAXLINES we'll put in it */
+
+static struct symtab *
+new_symtab (char *name, int maxsyms, int maxlines, struct objfile *objfile)
+{
+  struct symtab *s = allocate_symtab (name, objfile);
+
+  LINETABLE (s) = new_linetable (maxlines);
+
+  /* All symtabs must have at least two blocks */
+  BLOCKVECTOR (s) = new_bvect (2);
+  BLOCKVECTOR_BLOCK (BLOCKVECTOR (s), GLOBAL_BLOCK) = new_block (maxsyms);
+  BLOCKVECTOR_BLOCK (BLOCKVECTOR (s), STATIC_BLOCK) = new_block (maxsyms);
+  BLOCK_SUPERBLOCK (BLOCKVECTOR_BLOCK (BLOCKVECTOR (s), STATIC_BLOCK)) =
+    BLOCKVECTOR_BLOCK (BLOCKVECTOR (s), GLOBAL_BLOCK);
+
+  s->free_code = free_linetable;
+  s->debugformat = obsavestring ("ECOFF", 5,
+                                &objfile->symbol_obstack);
+  return (s);
+}
+
+/* Allocate a new partial_symtab NAME */
+
+static struct partial_symtab *
+new_psymtab (char *name, struct objfile *objfile)
+{
+  struct partial_symtab *psymtab;
+
+  psymtab = allocate_psymtab (name, objfile);
+  psymtab->section_offsets = objfile->section_offsets;
+
+  /* Keep a backpointer to the file's symbols */
+
+  psymtab->read_symtab_private = ((char *)
+                                 obstack_alloc (&objfile->psymbol_obstack,
+                                                sizeof (struct symloc)));
+  memset (psymtab->read_symtab_private, 0, sizeof (struct symloc));
+  CUR_BFD (psymtab) = cur_bfd;
+  DEBUG_SWAP (psymtab) = debug_swap;
+  DEBUG_INFO (psymtab) = debug_info;
+  PENDING_LIST (psymtab) = pending_list;
+
+  /* The way to turn this into a symtab is to call... */
+  psymtab->read_symtab = mdebug_psymtab_to_symtab;
+  return (psymtab);
+}
+
+
+/* Allocate a linetable array of the given SIZE.  Since the struct
+   already includes one item, we subtract one when calculating the
+   proper size to allocate.  */
+
+static struct linetable *
+new_linetable (int size)
+{
+  struct linetable *l;
+
+  size = (size - 1) * sizeof (l->item) + sizeof (struct linetable);
+  l = (struct linetable *) xmalloc (size);
+  l->nitems = 0;
+  return l;
+}
+
+/* Oops, too big. Shrink it.  This was important with the 2.4 linetables,
+   I am not so sure about the 3.4 ones.
+
+   Since the struct linetable already includes one item, we subtract one when
+   calculating the proper size to allocate.  */
+
+static struct linetable *
+shrink_linetable (struct linetable *lt)
+{
+
+  return (struct linetable *) xrealloc ((void *) lt,
+                                       (sizeof (struct linetable)
+                                        + ((lt->nitems - 1)
+                                           * sizeof (lt->item))));
+}
+
+/* Allocate and zero a new blockvector of NBLOCKS blocks. */
+
+static struct blockvector *
+new_bvect (int nblocks)
+{
+  struct blockvector *bv;
+  int size;
+
+  size = sizeof (struct blockvector) + nblocks * sizeof (struct block *);
+  bv = (struct blockvector *) xzalloc (size);
+
+  BLOCKVECTOR_NBLOCKS (bv) = nblocks;
+
+  return bv;
+}
+
+/* Allocate and zero a new block of MAXSYMS symbols */
+
+static struct block *
+new_block (int maxsyms)
+{
+  int size = sizeof (struct block) + (maxsyms - 1) * sizeof (struct symbol *);
+
+  return (struct block *) xzalloc (size);
+}
+
+/* Ooops, too big. Shrink block B in symtab S to its minimal size.
+   Shrink_block can also be used by add_symbol to grow a block.  */
+
+static struct block *
+shrink_block (struct block *b, struct symtab *s)
+{
+  struct block *new;
+  struct blockvector *bv = BLOCKVECTOR (s);
+  int i;
+
+  /* Just reallocate it and fix references to the old one */
+
+  new = (struct block *) xrealloc ((void *) b,
+                                  (sizeof (struct block)
+                                   + ((BLOCK_NSYMS (b) - 1)
+                                      * sizeof (struct symbol *))));
+
+  /* FIXME: Not worth hashing this block as it's built.  */
+  /* All callers should have created the block with new_block (), which
+     would mean it was not previously hashed.  Make sure.  */
+  gdb_assert (BLOCK_HASHTABLE (new) == 0);
+
+  /* Should chase pointers to old one.  Fortunately, that`s just
+     the block`s function and inferior blocks */
+  if (BLOCK_FUNCTION (new) && SYMBOL_BLOCK_VALUE (BLOCK_FUNCTION (new)) == b)
+    SYMBOL_BLOCK_VALUE (BLOCK_FUNCTION (new)) = new;
+  for (i = 0; i < BLOCKVECTOR_NBLOCKS (bv); i++)
+    if (BLOCKVECTOR_BLOCK (bv, i) == b)
+      BLOCKVECTOR_BLOCK (bv, i) = new;
+    else if (BLOCK_SUPERBLOCK (BLOCKVECTOR_BLOCK (bv, i)) == b)
+      BLOCK_SUPERBLOCK (BLOCKVECTOR_BLOCK (bv, i)) = new;
+  return new;
+}
+
+/* Create a new symbol with printname NAME */
+
+static struct symbol *
+new_symbol (char *name)
+{
+  struct symbol *s = ((struct symbol *)
+                     obstack_alloc (&current_objfile->symbol_obstack,
+                                    sizeof (struct symbol)));
+
+  memset (s, 0, sizeof (*s));
+  SYMBOL_NAME (s) = obsavestring (name, strlen (name),
+                                 &current_objfile->symbol_obstack);
+  SYMBOL_LANGUAGE (s) = psymtab_language;
+  SYMBOL_INIT_DEMANGLED_NAME (s, &current_objfile->symbol_obstack);
+  return s;
+}
+
+/* Create a new type with printname NAME */
+
+static struct type *
+new_type (char *name)
+{
+  struct type *t;
+
+  t = alloc_type (current_objfile);
+  TYPE_NAME (t) = name;
+  TYPE_CPLUS_SPECIFIC (t) = (struct cplus_struct_type *) &cplus_struct_default;
+  return t;
+}
+\f
+/* Read ECOFF debugging information from a BFD section.  This is
+   called from elfread.c.  It parses the section into a
+   ecoff_debug_info struct, and then lets the rest of the file handle
+   it as normal.  */
+
+void
+elfmdebug_build_psymtabs (struct objfile *objfile,
+                         const struct ecoff_debug_swap *swap, asection *sec)
+{
+  bfd *abfd = objfile->obfd;
+  struct ecoff_debug_info *info;
+
+  info = ((struct ecoff_debug_info *)
+         obstack_alloc (&objfile->psymbol_obstack,
+                        sizeof (struct ecoff_debug_info)));
+
+  if (!(*swap->read_debug_info) (abfd, sec, info))
+    error ("Error reading ECOFF debugging information: %s",
+          bfd_errmsg (bfd_get_error ()));
+
+  mdebug_build_psymtabs (objfile, swap, info);
+}
+\f
+
+/* Things used for calling functions in the inferior.
+   These functions are exported to our companion
+   mips-tdep.c file and are here because they play
+   with the symbol-table explicitly. */
+
+/* Sigtramp: make sure we have all the necessary information
+   about the signal trampoline code. Since the official code
+   from MIPS does not do so, we make up that information ourselves.
+   If they fix the library (unlikely) this code will neutralize itself. */
+
+/* FIXME: This function is called only by mips-tdep.c.  It needs to be
+   here because it calls functions defined in this file, but perhaps
+   this could be handled in a better way.  Only compile it in when
+   tm-mips.h is included. */
+
+#ifdef TM_MIPS_H
+
+void
+fixup_sigtramp (void)
+{
+  struct symbol *s;
+  struct symtab *st;
+  struct block *b, *b0 = NULL;
+
+  sigtramp_address = -1;
+
+  /* We have to handle the following cases here:
+     a) The Mips library has a sigtramp label within sigvec.
+     b) Irix has a _sigtramp which we want to use, but it also has sigvec.  */
+  s = lookup_symbol ("sigvec", 0, VAR_NAMESPACE, 0, NULL);
+  if (s != 0)
+    {
+      b0 = SYMBOL_BLOCK_VALUE (s);
+      s = lookup_symbol ("sigtramp", b0, VAR_NAMESPACE, 0, NULL);
+    }
+  if (s == 0)
+    {
+      /* No sigvec or no sigtramp inside sigvec, try _sigtramp.  */
+      s = lookup_symbol ("_sigtramp", 0, VAR_NAMESPACE, 0, NULL);
+    }
+
+  /* But maybe this program uses its own version of sigvec */
+  if (s == 0)
+    return;
+
+  /* Did we or MIPSco fix the library ? */
+  if (SYMBOL_CLASS (s) == LOC_BLOCK)
+    {
+      sigtramp_address = BLOCK_START (SYMBOL_BLOCK_VALUE (s));
+      sigtramp_end = BLOCK_END (SYMBOL_BLOCK_VALUE (s));
+      return;
+    }
+
+  sigtramp_address = SYMBOL_VALUE (s);
+  sigtramp_end = sigtramp_address + 0x88;      /* black magic */
+
+  /* But what symtab does it live in ? */
+  st = find_pc_symtab (SYMBOL_VALUE (s));
+
+  /*
+   * Ok, there goes the fix: turn it into a procedure, with all the
+   * needed info.  Note we make it a nested procedure of sigvec,
+   * which is the way the (assembly) code is actually written.
+   */
+  SYMBOL_NAMESPACE (s) = VAR_NAMESPACE;
+  SYMBOL_CLASS (s) = LOC_BLOCK;
+  SYMBOL_TYPE (s) = init_type (TYPE_CODE_FUNC, 4, 0, (char *) NULL,
+                              st->objfile);
+  TYPE_TARGET_TYPE (SYMBOL_TYPE (s)) = mdebug_type_void;
+
+  /* Need a block to allocate MIPS_EFI_SYMBOL_NAME in */
+  b = new_block (1);
+  SYMBOL_BLOCK_VALUE (s) = b;
+  BLOCK_START (b) = sigtramp_address;
+  BLOCK_END (b) = sigtramp_end;
+  BLOCK_FUNCTION (b) = s;
+  BLOCK_SUPERBLOCK (b) = BLOCK_SUPERBLOCK (b0);
+  add_block (b, st);
+  sort_blocks (st);
+
+  /* Make a MIPS_EFI_SYMBOL_NAME entry for it */
+  {
+    struct mips_extra_func_info *e =
+    ((struct mips_extra_func_info *)
+     xzalloc (sizeof (struct mips_extra_func_info)));
+
+    e->numargs = 0;            /* the kernel thinks otherwise */
+    e->pdr.frameoffset = 32;
+    e->pdr.framereg = SP_REGNUM;
+    /* Note that setting pcreg is no longer strictly necessary as
+       mips_frame_saved_pc is now aware of signal handler frames.  */
+    e->pdr.pcreg = PC_REGNUM;
+    e->pdr.regmask = -2;
+    /* Offset to saved r31, in the sigtramp case the saved registers
+       are above the frame in the sigcontext.
+       We have 4 alignment bytes, 12 bytes for onstack, mask and pc,
+       32 * 4 bytes for the general registers, 12 bytes for mdhi, mdlo, ownedfp
+       and 32 * 4 bytes for the floating point registers.  */
+    e->pdr.regoffset = 4 + 12 + 31 * 4;
+    e->pdr.fregmask = -1;
+    /* Offset to saved f30 (first saved *double* register).  */
+    e->pdr.fregoffset = 4 + 12 + 32 * 4 + 12 + 30 * 4;
+    e->pdr.isym = (long) s;
+    e->pdr.adr = sigtramp_address;
+
+    current_objfile = st->objfile;     /* Keep new_symbol happy */
+    s = new_symbol (MIPS_EFI_SYMBOL_NAME);
+    SYMBOL_VALUE (s) = (long) e;
+    SYMBOL_NAMESPACE (s) = LABEL_NAMESPACE;
+    SYMBOL_CLASS (s) = LOC_CONST;
+    SYMBOL_TYPE (s) = mdebug_type_void;
+    current_objfile = NULL;
+  }
+
+  BLOCK_SYM (b, BLOCK_NSYMS (b)++) = s;
+}
+
+#endif /* TM_MIPS_H */
+
+void
+_initialize_mdebugread (void)
+{
+  mdebug_type_void =
+    init_type (TYPE_CODE_VOID, 1,
+              0,
+              "void", (struct objfile *) NULL);
+  mdebug_type_char =
+    init_type (TYPE_CODE_INT, 1,
+              0,
+              "char", (struct objfile *) NULL);
+  mdebug_type_unsigned_char =
+    init_type (TYPE_CODE_INT, 1,
+              TYPE_FLAG_UNSIGNED,
+              "unsigned char", (struct objfile *) NULL);
+  mdebug_type_short =
+    init_type (TYPE_CODE_INT, 2,
+              0,
+              "short", (struct objfile *) NULL);
+  mdebug_type_unsigned_short =
+    init_type (TYPE_CODE_INT, 2,
+              TYPE_FLAG_UNSIGNED,
+              "unsigned short", (struct objfile *) NULL);
+  mdebug_type_int_32 =
+    init_type (TYPE_CODE_INT, 4,
+              0,
+              "int", (struct objfile *) NULL);
+  mdebug_type_unsigned_int_32 =
+    init_type (TYPE_CODE_INT, 4,
+              TYPE_FLAG_UNSIGNED,
+              "unsigned int", (struct objfile *) NULL);
+  mdebug_type_int_64 =
+    init_type (TYPE_CODE_INT, 8,
+              0,
+              "int", (struct objfile *) NULL);
+  mdebug_type_unsigned_int_64 =
+    init_type (TYPE_CODE_INT, 8,
+              TYPE_FLAG_UNSIGNED,
+              "unsigned int", (struct objfile *) NULL);
+  mdebug_type_long_32 =
+    init_type (TYPE_CODE_INT, 4,
+              0,
+              "long", (struct objfile *) NULL);
+  mdebug_type_unsigned_long_32 =
+    init_type (TYPE_CODE_INT, 4,
+              TYPE_FLAG_UNSIGNED,
+              "unsigned long", (struct objfile *) NULL);
+  mdebug_type_long_64 =
+    init_type (TYPE_CODE_INT, 8,
+              0,
+              "long", (struct objfile *) NULL);
+  mdebug_type_unsigned_long_64 =
+    init_type (TYPE_CODE_INT, 8,
+              TYPE_FLAG_UNSIGNED,
+              "unsigned long", (struct objfile *) NULL);
+  mdebug_type_long_long_64 =
+    init_type (TYPE_CODE_INT, 8,
+              0,
+              "long long", (struct objfile *) NULL);
+  mdebug_type_unsigned_long_long_64 =
+    init_type (TYPE_CODE_INT, 8,
+              TYPE_FLAG_UNSIGNED,
+              "unsigned long long", (struct objfile *) NULL);
+  mdebug_type_adr_32 =
+    init_type (TYPE_CODE_PTR, 4,
+              TYPE_FLAG_UNSIGNED,
+              "adr_32", (struct objfile *) NULL);
+  TYPE_TARGET_TYPE (mdebug_type_adr_32) = mdebug_type_void;
+  mdebug_type_adr_64 =
+    init_type (TYPE_CODE_PTR, 8,
+              TYPE_FLAG_UNSIGNED,
+              "adr_64", (struct objfile *) NULL);
+  TYPE_TARGET_TYPE (mdebug_type_adr_64) = mdebug_type_void;
+  mdebug_type_float =
+    init_type (TYPE_CODE_FLT, TARGET_FLOAT_BIT / TARGET_CHAR_BIT,
+              0,
+              "float", (struct objfile *) NULL);
+  mdebug_type_double =
+    init_type (TYPE_CODE_FLT, TARGET_DOUBLE_BIT / TARGET_CHAR_BIT,
+              0,
+              "double", (struct objfile *) NULL);
+  mdebug_type_complex =
+    init_type (TYPE_CODE_COMPLEX, 2 * TARGET_FLOAT_BIT / TARGET_CHAR_BIT,
+              0,
+              "complex", (struct objfile *) NULL);
+  TYPE_TARGET_TYPE (mdebug_type_complex) = mdebug_type_float;
+  mdebug_type_double_complex =
+    init_type (TYPE_CODE_COMPLEX, 2 * TARGET_DOUBLE_BIT / TARGET_CHAR_BIT,
+              0,
+              "double complex", (struct objfile *) NULL);
+  TYPE_TARGET_TYPE (mdebug_type_double_complex) = mdebug_type_double;
+
+  /* Is a "string" the way btString means it the same as TYPE_CODE_STRING?
+     FIXME.  */
+  mdebug_type_string =
+    init_type (TYPE_CODE_STRING,
+              TARGET_CHAR_BIT / TARGET_CHAR_BIT,
+              0, "string",
+              (struct objfile *) NULL);
+
+  /* We use TYPE_CODE_INT to print these as integers.  Does this do any
+     good?  Would we be better off with TYPE_CODE_ERROR?  Should
+     TYPE_CODE_ERROR print things in hex if it knows the size?  */
+  mdebug_type_fixed_dec =
+    init_type (TYPE_CODE_INT,
+              TARGET_INT_BIT / TARGET_CHAR_BIT,
+              0, "fixed decimal",
+              (struct objfile *) NULL);
+
+  mdebug_type_float_dec =
+    init_type (TYPE_CODE_ERROR,
+              TARGET_DOUBLE_BIT / TARGET_CHAR_BIT,
+              0, "floating decimal",
+              (struct objfile *) NULL);
+
+  nodebug_func_symbol_type = init_type (TYPE_CODE_FUNC, 1, 0,
+                                       "<function, no debug info>", NULL);
+  TYPE_TARGET_TYPE (nodebug_func_symbol_type) = mdebug_type_int;
+  nodebug_var_symbol_type =
+    init_type (TYPE_CODE_INT, TARGET_INT_BIT / HOST_CHAR_BIT, 0,
+              "<variable, no debug info>", NULL);
+}
diff --git a/gdb/symfile.c b/gdb/symfile.c
new file mode 100644 (file)
index 0000000..66bbf71
--- /dev/null
@@ -0,0 +1,3340 @@
+/* Generic symbol file reading for the GNU debugger, GDB.
+
+   Copyright 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998,
+   1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+
+   Contributed by Cygnus Support, using pieces from other GDB modules.
+
+   This file is part of GDB.
+
+   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.  */
+
+#include "defs.h"
+#include "symtab.h"
+#include "gdbtypes.h"
+#include "gdbcore.h"
+#include "frame.h"
+#include "target.h"
+#include "value.h"
+#include "symfile.h"
+#include "objfiles.h"
+#include "source.h"
+#include "gdbcmd.h"
+#include "breakpoint.h"
+#include "language.h"
+#include "complaints.h"
+#include "demangle.h"
+#include "inferior.h"          /* for write_pc */
+#include "gdb-stabs.h"
+#include "gdb_obstack.h"
+#include "completer.h"
+#include "bcache.h"
+
+#include <sys/types.h>
+#include <fcntl.h>
+#include "gdb_string.h"
+#include "gdb_stat.h"
+#include <ctype.h>
+#include <time.h>
+
+#ifndef O_BINARY
+#define O_BINARY 0
+#endif
+
+#ifdef HPUXHPPA
+
+/* Some HP-UX related globals to clear when a new "main"
+   symbol file is loaded. HP-specific.  */
+
+extern int hp_som_som_object_present;
+extern int hp_cxx_exception_support_initialized;
+#define RESET_HP_UX_GLOBALS() do {\
+                                    hp_som_som_object_present = 0;             /* indicates HP-compiled code */        \
+                                    hp_cxx_exception_support_initialized = 0;  /* must reinitialize exception stuff */ \
+                              } while (0)
+#endif
+
+int (*ui_load_progress_hook) (const char *section, unsigned long num);
+void (*show_load_progress) (const char *section,
+                           unsigned long section_sent, 
+                           unsigned long section_size, 
+                           unsigned long total_sent, 
+                           unsigned long total_size);
+void (*pre_add_symbol_hook) (char *);
+void (*post_add_symbol_hook) (void);
+void (*target_new_objfile_hook) (struct objfile *);
+
+static void clear_symtab_users_cleanup (void *ignore);
+
+/* Global variables owned by this file */
+int readnow_symbol_files;      /* Read full symbols immediately */
+
+/* External variables and functions referenced. */
+
+extern void report_transfer_performance (unsigned long, time_t, time_t);
+
+/* Functions this file defines */
+
+#if 0
+static int simple_read_overlay_region_table (void);
+static void simple_free_overlay_region_table (void);
+#endif
+
+static void set_initial_language (void);
+
+static void load_command (char *, int);
+
+static void symbol_file_add_main_1 (char *args, int from_tty, int flags);
+
+static void add_symbol_file_command (char *, int);
+
+static void add_shared_symbol_files_command (char *, int);
+
+static void cashier_psymtab (struct partial_symtab *);
+
+bfd *symfile_bfd_open (char *);
+
+int get_section_index (struct objfile *, char *);
+
+static void find_sym_fns (struct objfile *);
+
+static void decrement_reading_symtab (void *);
+
+static void overlay_invalidate_all (void);
+
+static int overlay_is_mapped (struct obj_section *);
+
+void list_overlays_command (char *, int);
+
+void map_overlay_command (char *, int);
+
+void unmap_overlay_command (char *, int);
+
+static void overlay_auto_command (char *, int);
+
+static void overlay_manual_command (char *, int);
+
+static void overlay_off_command (char *, int);
+
+static void overlay_load_command (char *, int);
+
+static void overlay_command (char *, int);
+
+static void simple_free_overlay_table (void);
+
+static void read_target_long_array (CORE_ADDR, unsigned int *, int);
+
+static int simple_read_overlay_table (void);
+
+static int simple_overlay_update_1 (struct obj_section *);
+
+static void add_filename_language (char *ext, enum language lang);
+
+static void set_ext_lang_command (char *args, int from_tty);
+
+static void info_ext_lang_command (char *args, int from_tty);
+
+static void init_filename_language_table (void);
+
+void _initialize_symfile (void);
+
+/* List of all available sym_fns.  On gdb startup, each object file reader
+   calls add_symtab_fns() to register information on each format it is
+   prepared to read. */
+
+static struct sym_fns *symtab_fns = NULL;
+
+/* Flag for whether user will be reloading symbols multiple times.
+   Defaults to ON for VxWorks, otherwise OFF.  */
+
+#ifdef SYMBOL_RELOADING_DEFAULT
+int symbol_reloading = SYMBOL_RELOADING_DEFAULT;
+#else
+int symbol_reloading = 0;
+#endif
+
+/* If non-zero, shared library symbols will be added automatically
+   when the inferior is created, new libraries are loaded, or when
+   attaching to the inferior.  This is almost always what users will
+   want to have happen; but for very large programs, the startup time
+   will be excessive, and so if this is a problem, the user can clear
+   this flag and then add the shared library symbols as needed.  Note
+   that there is a potential for confusion, since if the shared
+   library symbols are not loaded, commands like "info fun" will *not*
+   report all the functions that are actually present. */
+
+int auto_solib_add = 1;
+
+/* For systems that support it, a threshold size in megabytes.  If
+   automatically adding a new library's symbol table to those already
+   known to the debugger would cause the total shared library symbol
+   size to exceed this threshhold, then the shlib's symbols are not
+   added.  The threshold is ignored if the user explicitly asks for a
+   shlib to be added, such as when using the "sharedlibrary"
+   command. */
+
+int auto_solib_limit;
+\f
+
+/* Since this function is called from within qsort, in an ANSI environment
+   it must conform to the prototype for qsort, which specifies that the
+   comparison function takes two "void *" pointers. */
+
+static int
+compare_symbols (const void *s1p, const void *s2p)
+{
+  register struct symbol **s1, **s2;
+
+  s1 = (struct symbol **) s1p;
+  s2 = (struct symbol **) s2p;
+  return (strcmp (SYMBOL_SOURCE_NAME (*s1), SYMBOL_SOURCE_NAME (*s2)));
+}
+
+/*
+
+   LOCAL FUNCTION
+
+   compare_psymbols -- compare two partial symbols by name
+
+   DESCRIPTION
+
+   Given pointers to pointers to two partial symbol table entries,
+   compare them by name and return -N, 0, or +N (ala strcmp).
+   Typically used by sorting routines like qsort().
+
+   NOTES
+
+   Does direct compare of first two characters before punting
+   and passing to strcmp for longer compares.  Note that the
+   original version had a bug whereby two null strings or two
+   identically named one character strings would return the
+   comparison of memory following the null byte.
+
+ */
+
+static int
+compare_psymbols (const void *s1p, const void *s2p)
+{
+  register struct partial_symbol **s1, **s2;
+  register char *st1, *st2;
+
+  s1 = (struct partial_symbol **) s1p;
+  s2 = (struct partial_symbol **) s2p;
+  st1 = SYMBOL_SOURCE_NAME (*s1);
+  st2 = SYMBOL_SOURCE_NAME (*s2);
+
+
+  if ((st1[0] - st2[0]) || !st1[0])
+    {
+      return (st1[0] - st2[0]);
+    }
+  else if ((st1[1] - st2[1]) || !st1[1])
+    {
+      return (st1[1] - st2[1]);
+    }
+  else
+    {
+      return (strcmp (st1, st2));
+    }
+}
+
+void
+sort_pst_symbols (struct partial_symtab *pst)
+{
+  /* Sort the global list; don't sort the static list */
+
+  qsort (pst->objfile->global_psymbols.list + pst->globals_offset,
+        pst->n_global_syms, sizeof (struct partial_symbol *),
+        compare_psymbols);
+}
+
+/* Call sort_block_syms to sort alphabetically the symbols of one block.  */
+
+void
+sort_block_syms (register struct block *b)
+{
+  qsort (&BLOCK_SYM (b, 0), BLOCK_NSYMS (b),
+        sizeof (struct symbol *), compare_symbols);
+}
+
+/* Call sort_symtab_syms to sort alphabetically
+   the symbols of each block of one symtab.  */
+
+void
+sort_symtab_syms (register struct symtab *s)
+{
+  register struct blockvector *bv;
+  int nbl;
+  int i;
+  register struct block *b;
+
+  if (s == 0)
+    return;
+  bv = BLOCKVECTOR (s);
+  nbl = BLOCKVECTOR_NBLOCKS (bv);
+  for (i = 0; i < nbl; i++)
+    {
+      b = BLOCKVECTOR_BLOCK (bv, i);
+      if (BLOCK_SHOULD_SORT (b))
+       sort_block_syms (b);
+    }
+}
+
+/* Make a null terminated copy of the string at PTR with SIZE characters in
+   the obstack pointed to by OBSTACKP .  Returns the address of the copy.
+   Note that the string at PTR does not have to be null terminated, I.E. it
+   may be part of a larger string and we are only saving a substring. */
+
+char *
+obsavestring (char *ptr, int size, struct obstack *obstackp)
+{
+  register char *p = (char *) obstack_alloc (obstackp, size + 1);
+  /* Open-coded memcpy--saves function call time.  These strings are usually
+     short.  FIXME: Is this really still true with a compiler that can
+     inline memcpy? */
+  {
+    register char *p1 = ptr;
+    register char *p2 = p;
+    char *end = ptr + size;
+    while (p1 != end)
+      *p2++ = *p1++;
+  }
+  p[size] = 0;
+  return p;
+}
+
+/* Concatenate strings S1, S2 and S3; return the new string.  Space is found
+   in the obstack pointed to by OBSTACKP.  */
+
+char *
+obconcat (struct obstack *obstackp, const char *s1, const char *s2,
+         const char *s3)
+{
+  register int len = strlen (s1) + strlen (s2) + strlen (s3) + 1;
+  register char *val = (char *) obstack_alloc (obstackp, len);
+  strcpy (val, s1);
+  strcat (val, s2);
+  strcat (val, s3);
+  return val;
+}
+
+/* True if we are nested inside psymtab_to_symtab. */
+
+int currently_reading_symtab = 0;
+
+static void
+decrement_reading_symtab (void *dummy)
+{
+  currently_reading_symtab--;
+}
+
+/* Get the symbol table that corresponds to a partial_symtab.
+   This is fast after the first time you do it.  In fact, there
+   is an even faster macro PSYMTAB_TO_SYMTAB that does the fast
+   case inline.  */
+
+struct symtab *
+psymtab_to_symtab (register struct partial_symtab *pst)
+{
+  /* If it's been looked up before, return it. */
+  if (pst->symtab)
+    return pst->symtab;
+
+  /* If it has not yet been read in, read it.  */
+  if (!pst->readin)
+    {
+      struct cleanup *back_to = make_cleanup (decrement_reading_symtab, NULL);
+      currently_reading_symtab++;
+      (*pst->read_symtab) (pst);
+      do_cleanups (back_to);
+    }
+
+  return pst->symtab;
+}
+
+/* Initialize entry point information for this objfile. */
+
+void
+init_entry_point_info (struct objfile *objfile)
+{
+  /* Save startup file's range of PC addresses to help blockframe.c
+     decide where the bottom of the stack is.  */
+
+  if (bfd_get_file_flags (objfile->obfd) & EXEC_P)
+    {
+      /* Executable file -- record its entry point so we'll recognize
+         the startup file because it contains the entry point.  */
+      objfile->ei.entry_point = bfd_get_start_address (objfile->obfd);
+    }
+  else
+    {
+      /* Examination of non-executable.o files.  Short-circuit this stuff.  */
+      objfile->ei.entry_point = INVALID_ENTRY_POINT;
+    }
+  objfile->ei.entry_file_lowpc = INVALID_ENTRY_LOWPC;
+  objfile->ei.entry_file_highpc = INVALID_ENTRY_HIGHPC;
+  objfile->ei.entry_func_lowpc = INVALID_ENTRY_LOWPC;
+  objfile->ei.entry_func_highpc = INVALID_ENTRY_HIGHPC;
+  objfile->ei.main_func_lowpc = INVALID_ENTRY_LOWPC;
+  objfile->ei.main_func_highpc = INVALID_ENTRY_HIGHPC;
+}
+
+/* Get current entry point address.  */
+
+CORE_ADDR
+entry_point_address (void)
+{
+  return symfile_objfile ? symfile_objfile->ei.entry_point : 0;
+}
+
+/* Remember the lowest-addressed loadable section we've seen.  
+   This function is called via bfd_map_over_sections. 
+
+   In case of equal vmas, the section with the largest size becomes the
+   lowest-addressed loadable section.
+
+   If the vmas and sizes are equal, the last section is considered the
+   lowest-addressed loadable section.  */
+
+void
+find_lowest_section (bfd *abfd, asection *sect, PTR obj)
+{
+  asection **lowest = (asection **) obj;
+
+  if (0 == (bfd_get_section_flags (abfd, sect) & SEC_LOAD))
+    return;
+  if (!*lowest)
+    *lowest = sect;            /* First loadable section */
+  else if (bfd_section_vma (abfd, *lowest) > bfd_section_vma (abfd, sect))
+    *lowest = sect;            /* A lower loadable section */
+  else if (bfd_section_vma (abfd, *lowest) == bfd_section_vma (abfd, sect)
+          && (bfd_section_size (abfd, (*lowest))
+              <= bfd_section_size (abfd, sect)))
+    *lowest = sect;
+}
+
+
+/* Build (allocate and populate) a section_addr_info struct from
+   an existing section table. */
+
+extern struct section_addr_info *
+build_section_addr_info_from_section_table (const struct section_table *start,
+                                            const struct section_table *end)
+{
+  struct section_addr_info *sap;
+  const struct section_table *stp;
+  int oidx;
+
+  sap = xmalloc (sizeof (struct section_addr_info));
+  memset (sap, 0, sizeof (struct section_addr_info));
+
+  for (stp = start, oidx = 0; stp != end; stp++)
+    {
+      if (bfd_get_section_flags (stp->bfd, 
+                                stp->the_bfd_section) & (SEC_ALLOC | SEC_LOAD)
+         && oidx < MAX_SECTIONS)
+       {
+         sap->other[oidx].addr = stp->addr;
+         sap->other[oidx].name 
+           = xstrdup (bfd_section_name (stp->bfd, stp->the_bfd_section));
+         sap->other[oidx].sectindex = stp->the_bfd_section->index;
+         oidx++;
+       }
+    }
+
+  return sap;
+}
+
+
+/* Free all memory allocated by build_section_addr_info_from_section_table. */
+
+extern void
+free_section_addr_info (struct section_addr_info *sap)
+{
+  int idx;
+
+  for (idx = 0; idx < MAX_SECTIONS; idx++)
+    if (sap->other[idx].name)
+      xfree (sap->other[idx].name);
+  xfree (sap);
+}
+
+
+/* Parse the user's idea of an offset for dynamic linking, into our idea
+   of how to represent it for fast symbol reading.  This is the default 
+   version of the sym_fns.sym_offsets function for symbol readers that
+   don't need to do anything special.  It allocates a section_offsets table
+   for the objectfile OBJFILE and stuffs ADDR into all of the offsets.  */
+
+void
+default_symfile_offsets (struct objfile *objfile,
+                        struct section_addr_info *addrs)
+{
+  int i;
+  asection *sect = NULL;
+
+  objfile->num_sections = SECT_OFF_MAX;
+  objfile->section_offsets = (struct section_offsets *)
+    obstack_alloc (&objfile->psymbol_obstack, SIZEOF_SECTION_OFFSETS);
+  memset (objfile->section_offsets, 0, SIZEOF_SECTION_OFFSETS);
+
+  /* Now calculate offsets for section that were specified by the
+     caller. */
+  for (i = 0; i < MAX_SECTIONS && addrs->other[i].name; i++)
+    {
+      struct other_sections *osp ;
+
+      osp = &addrs->other[i] ;
+      if (osp->addr == 0)
+       continue;
+
+      /* Record all sections in offsets */
+      /* The section_offsets in the objfile are here filled in using
+         the BFD index. */
+      (objfile->section_offsets)->offsets[osp->sectindex] = osp->addr;
+    }
+
+  /* Remember the bfd indexes for the .text, .data, .bss and
+     .rodata sections. */
+
+  sect = bfd_get_section_by_name (objfile->obfd, ".text");
+  if (sect) 
+    objfile->sect_index_text = sect->index;
+
+  sect = bfd_get_section_by_name (objfile->obfd, ".data");
+  if (sect) 
+    objfile->sect_index_data = sect->index;
+
+  sect = bfd_get_section_by_name (objfile->obfd, ".bss");
+  if (sect) 
+    objfile->sect_index_bss = sect->index;
+
+  sect = bfd_get_section_by_name (objfile->obfd, ".rodata");
+  if (sect) 
+    objfile->sect_index_rodata = sect->index;
+
+  /* This is where things get really weird...  We MUST have valid
+     indices for the various sect_index_* members or gdb will abort.
+     So if for example, there is no ".text" section, we have to
+     accomodate that.  Except when explicitly adding symbol files at
+     some address, section_offsets contains nothing but zeros, so it
+     doesn't matter which slot in section_offsets the individual
+     sect_index_* members index into.  So if they are all zero, it is
+     safe to just point all the currently uninitialized indices to the
+     first slot. */
+
+  for (i = 0; i < objfile->num_sections; i++)
+    {
+      if (ANOFFSET (objfile->section_offsets, i) != 0)
+       {
+         break;
+       }
+    }
+  if (i == objfile->num_sections)
+    {
+      if (objfile->sect_index_text == -1)
+       objfile->sect_index_text = 0;
+      if (objfile->sect_index_data == -1)
+       objfile->sect_index_data = 0;
+      if (objfile->sect_index_bss == -1)
+       objfile->sect_index_bss = 0;
+      if (objfile->sect_index_rodata == -1)
+       objfile->sect_index_rodata = 0;
+    }
+}
+
+/* Process a symbol file, as either the main file or as a dynamically
+   loaded file.
+
+   OBJFILE is where the symbols are to be read from.
+
+   ADDR is the address where the text segment was loaded, unless the
+   objfile is the main symbol file, in which case it is zero.
+
+   MAINLINE is nonzero if this is the main symbol file, or zero if
+   it's an extra symbol file such as dynamically loaded code.
+
+   VERBO is nonzero if the caller has printed a verbose message about
+   the symbol reading (and complaints can be more terse about it).  */
+
+void
+syms_from_objfile (struct objfile *objfile, struct section_addr_info *addrs,
+                  int mainline, int verbo)
+{
+  asection *lower_sect;
+  asection *sect;
+  CORE_ADDR lower_offset;
+  struct section_addr_info local_addr;
+  struct cleanup *old_chain;
+  int i;
+
+  /* If ADDRS is NULL, initialize the local section_addr_info struct and
+     point ADDRS to it.  We now establish the convention that an addr of
+     zero means no load address was specified. */
+
+  if (addrs == NULL)
+    {
+      memset (&local_addr, 0, sizeof (local_addr));
+      addrs = &local_addr;
+    }
+
+  init_entry_point_info (objfile);
+  find_sym_fns (objfile);
+
+  if (objfile->sf == NULL)
+    return;    /* No symbols. */
+
+  /* Make sure that partially constructed symbol tables will be cleaned up
+     if an error occurs during symbol reading.  */
+  old_chain = make_cleanup_free_objfile (objfile);
+
+  if (mainline)
+    {
+      /* We will modify the main symbol table, make sure that all its users
+         will be cleaned up if an error occurs during symbol reading.  */
+      make_cleanup (clear_symtab_users_cleanup, 0 /*ignore*/);
+
+      /* Since no error yet, throw away the old symbol table.  */
+
+      if (symfile_objfile != NULL)
+       {
+         free_objfile (symfile_objfile);
+         symfile_objfile = NULL;
+       }
+
+      /* Currently we keep symbols from the add-symbol-file command.
+         If the user wants to get rid of them, they should do "symbol-file"
+         without arguments first.  Not sure this is the best behavior
+         (PR 2207).  */
+
+      (*objfile->sf->sym_new_init) (objfile);
+    }
+
+  /* Convert addr into an offset rather than an absolute address.
+     We find the lowest address of a loaded segment in the objfile,
+     and assume that <addr> is where that got loaded.
+
+     We no longer warn if the lowest section is not a text segment (as
+     happens for the PA64 port.  */
+  if (!mainline)
+    {
+      /* Find lowest loadable section to be used as starting point for 
+         continguous sections. FIXME!! won't work without call to find
+        .text first, but this assumes text is lowest section. */
+      lower_sect = bfd_get_section_by_name (objfile->obfd, ".text");
+      if (lower_sect == NULL)
+       bfd_map_over_sections (objfile->obfd, find_lowest_section,
+                              (PTR) &lower_sect);
+      if (lower_sect == NULL)
+       warning ("no loadable sections found in added symbol-file %s",
+                objfile->name);
+      else 
+       if ((bfd_get_section_flags (objfile->obfd, lower_sect) & SEC_CODE) == 0)
+         warning ("Lowest section in %s is %s at %s",
+                  objfile->name,
+                  bfd_section_name (objfile->obfd, lower_sect),
+                  paddr (bfd_section_vma (objfile->obfd, lower_sect)));
+      if (lower_sect != NULL)
+       lower_offset = bfd_section_vma (objfile->obfd, lower_sect);
+      else
+       lower_offset = 0;
+       /* Calculate offsets for the loadable sections.
+        FIXME! Sections must be in order of increasing loadable section
+        so that contiguous sections can use the lower-offset!!!
+          Adjust offsets if the segments are not contiguous.
+          If the section is contiguous, its offset should be set to
+        the offset of the highest loadable section lower than it
+        (the loadable section directly below it in memory).
+        this_offset = lower_offset = lower_addr - lower_orig_addr */
+
+       /* Calculate offsets for sections. */
+      for (i=0 ; i < MAX_SECTIONS && addrs->other[i].name; i++)
+       {
+         if (addrs->other[i].addr != 0)
+           {
+             sect = bfd_get_section_by_name (objfile->obfd, addrs->other[i].name);
+             if (sect)
+               {
+                 addrs->other[i].addr -= bfd_section_vma (objfile->obfd, sect);
+                 lower_offset = addrs->other[i].addr;
+                 /* This is the index used by BFD. */
+                 addrs->other[i].sectindex = sect->index ;
+               }
+             else
+               {
+                 warning ("section %s not found in %s", addrs->other[i].name, 
+                          objfile->name);
+                 addrs->other[i].addr = 0;
+               }
+           }
+         else
+           addrs->other[i].addr = lower_offset;
+       }
+    }
+
+  /* Initialize symbol reading routines for this objfile, allow complaints to
+     appear for this new file, and record how verbose to be, then do the
+     initial symbol reading for this file. */
+
+  (*objfile->sf->sym_init) (objfile);
+  clear_complaints (&symfile_complaints, 1, verbo);
+
+  (*objfile->sf->sym_offsets) (objfile, addrs);
+
+#ifndef IBM6000_TARGET
+  /* This is a SVR4/SunOS specific hack, I think.  In any event, it
+     screws RS/6000.  sym_offsets should be doing this sort of thing,
+     because it knows the mapping between bfd sections and
+     section_offsets.  */
+  /* This is a hack.  As far as I can tell, section offsets are not
+     target dependent.  They are all set to addr with a couple of
+     exceptions.  The exceptions are sysvr4 shared libraries, whose
+     offsets are kept in solib structures anyway and rs6000 xcoff
+     which handles shared libraries in a completely unique way.
+
+     Section offsets are built similarly, except that they are built
+     by adding addr in all cases because there is no clear mapping
+     from section_offsets into actual sections.  Note that solib.c
+     has a different algorithm for finding section offsets.
+
+     These should probably all be collapsed into some target
+     independent form of shared library support.  FIXME.  */
+
+  if (addrs)
+    {
+      struct obj_section *s;
+
+       /* Map section offsets in "addr" back to the object's 
+          sections by comparing the section names with bfd's 
+          section names.  Then adjust the section address by
+          the offset. */ /* for gdb/13815 */
+      ALL_OBJFILE_OSECTIONS (objfile, s)
+       {
+         CORE_ADDR s_addr = 0;
+         int i;
+
+           for (i = 0; 
+                !s_addr && i < MAX_SECTIONS && addrs->other[i].name;
+                i++)
+             if (strcmp (bfd_section_name (s->objfile->obfd, 
+                                           s->the_bfd_section), 
+                         addrs->other[i].name) == 0)
+               s_addr = addrs->other[i].addr; /* end added for gdb/13815 */
+         s->addr -= s->offset;
+         s->addr += s_addr;
+         s->endaddr -= s->offset;
+         s->endaddr += s_addr;
+         s->offset += s_addr;
+       }
+    }
+#endif /* not IBM6000_TARGET */
+
+  (*objfile->sf->sym_read) (objfile, mainline);
+
+  if (!have_partial_symbols () && !have_full_symbols ())
+    {
+      wrap_here ("");
+      printf_filtered ("(no debugging symbols found)...");
+      wrap_here ("");
+    }
+
+  /* Don't allow char * to have a typename (else would get caddr_t).
+     Ditto void *.  FIXME: Check whether this is now done by all the
+     symbol readers themselves (many of them now do), and if so remove
+     it from here.  */
+
+  TYPE_NAME (lookup_pointer_type (builtin_type_char)) = 0;
+  TYPE_NAME (lookup_pointer_type (builtin_type_void)) = 0;
+
+  /* Mark the objfile has having had initial symbol read attempted.  Note
+     that this does not mean we found any symbols... */
+
+  objfile->flags |= OBJF_SYMS;
+
+  /* Discard cleanups as symbol reading was successful.  */
+
+  discard_cleanups (old_chain);
+
+  /* Call this after reading in a new symbol table to give target
+     dependent code a crack at the new symbols.  For instance, this
+     could be used to update the values of target-specific symbols GDB
+     needs to keep track of (such as _sigtramp, or whatever).  */
+
+  TARGET_SYMFILE_POSTREAD (objfile);
+}
+
+/* Perform required actions after either reading in the initial
+   symbols for a new objfile, or mapping in the symbols from a reusable
+   objfile. */
+
+void
+new_symfile_objfile (struct objfile *objfile, int mainline, int verbo)
+{
+
+  /* If this is the main symbol file we have to clean up all users of the
+     old main symbol file. Otherwise it is sufficient to fixup all the
+     breakpoints that may have been redefined by this symbol file.  */
+  if (mainline)
+    {
+      /* OK, make it the "real" symbol file.  */
+      symfile_objfile = objfile;
+
+      clear_symtab_users ();
+    }
+  else
+    {
+      breakpoint_re_set ();
+    }
+
+  /* We're done reading the symbol file; finish off complaints.  */
+  clear_complaints (&symfile_complaints, 0, verbo);
+}
+
+/* Process a symbol file, as either the main file or as a dynamically
+   loaded file.
+
+   NAME is the file name (which will be tilde-expanded and made
+   absolute herein) (but we don't free or modify NAME itself).
+   FROM_TTY says how verbose to be.  MAINLINE specifies whether this
+   is the main symbol file, or whether it's an extra symbol file such
+   as dynamically loaded code.  If !mainline, ADDR is the address
+   where the text segment was loaded.
+
+   Upon success, returns a pointer to the objfile that was added.
+   Upon failure, jumps back to command level (never returns). */
+
+struct objfile *
+symbol_file_add (char *name, int from_tty, struct section_addr_info *addrs,
+                int mainline, int flags)
+{
+  struct objfile *objfile;
+  struct partial_symtab *psymtab;
+  bfd *abfd;
+
+  /* Open a bfd for the file, and give user a chance to burp if we'd be
+     interactively wiping out any existing symbols.  */
+
+  abfd = symfile_bfd_open (name);
+
+  if ((have_full_symbols () || have_partial_symbols ())
+      && mainline
+      && from_tty
+      && !query ("Load new symbol table from \"%s\"? ", name))
+    error ("Not confirmed.");
+
+  objfile = allocate_objfile (abfd, flags);
+
+  /* If the objfile uses a mapped symbol file, and we have a psymtab for
+     it, then skip reading any symbols at this time. */
+
+  if ((objfile->flags & OBJF_MAPPED) && (objfile->flags & OBJF_SYMS))
+    {
+      /* We mapped in an existing symbol table file that already has had
+         initial symbol reading performed, so we can skip that part.  Notify
+         the user that instead of reading the symbols, they have been mapped.
+       */
+      if (from_tty || info_verbose)
+       {
+         printf_filtered ("Mapped symbols for %s...", name);
+         wrap_here ("");
+         gdb_flush (gdb_stdout);
+       }
+      init_entry_point_info (objfile);
+      find_sym_fns (objfile);
+    }
+  else
+    {
+      /* We either created a new mapped symbol table, mapped an existing
+         symbol table file which has not had initial symbol reading
+         performed, or need to read an unmapped symbol table. */
+      if (from_tty || info_verbose)
+       {
+         if (pre_add_symbol_hook)
+           pre_add_symbol_hook (name);
+         else
+           {
+             printf_filtered ("Reading symbols from %s...", name);
+             wrap_here ("");
+             gdb_flush (gdb_stdout);
+           }
+       }
+      syms_from_objfile (objfile, addrs, mainline, from_tty);
+    }
+
+  /* We now have at least a partial symbol table.  Check to see if the
+     user requested that all symbols be read on initial access via either
+     the gdb startup command line or on a per symbol file basis.  Expand
+     all partial symbol tables for this objfile if so. */
+
+  if ((flags & OBJF_READNOW) || readnow_symbol_files)
+    {
+      if (from_tty || info_verbose)
+       {
+         printf_filtered ("expanding to full symbols...");
+         wrap_here ("");
+         gdb_flush (gdb_stdout);
+       }
+
+      for (psymtab = objfile->psymtabs;
+          psymtab != NULL;
+          psymtab = psymtab->next)
+       {
+         psymtab_to_symtab (psymtab);
+       }
+    }
+
+  if (from_tty || info_verbose)
+    {
+      if (post_add_symbol_hook)
+       post_add_symbol_hook ();
+      else
+       {
+         printf_filtered ("done.\n");
+         gdb_flush (gdb_stdout);
+       }
+    }
+
+  if (objfile->sf == NULL)
+    return objfile;    /* No symbols. */
+
+  new_symfile_objfile (objfile, mainline, from_tty);
+
+  if (target_new_objfile_hook)
+    target_new_objfile_hook (objfile);
+
+  return (objfile);
+}
+
+/* Call symbol_file_add() with default values and update whatever is
+   affected by the loading of a new main().
+   Used when the file is supplied in the gdb command line
+   and by some targets with special loading requirements.
+   The auxiliary function, symbol_file_add_main_1(), has the flags
+   argument for the switches that can only be specified in the symbol_file
+   command itself.  */
+   
+void
+symbol_file_add_main (char *args, int from_tty)
+{
+  symbol_file_add_main_1 (args, from_tty, 0);
+}
+
+static void
+symbol_file_add_main_1 (char *args, int from_tty, int flags)
+{
+  symbol_file_add (args, from_tty, NULL, 1, flags);
+
+#ifdef HPUXHPPA
+  RESET_HP_UX_GLOBALS ();
+#endif
+
+  /* Getting new symbols may change our opinion about
+     what is frameless.  */
+  reinit_frame_cache ();
+
+  set_initial_language ();
+}
+
+void
+symbol_file_clear (int from_tty)
+{
+  if ((have_full_symbols () || have_partial_symbols ())
+      && from_tty
+      && !query ("Discard symbol table from `%s'? ",
+                symfile_objfile->name))
+    error ("Not confirmed.");
+    free_all_objfiles ();
+
+    /* solib descriptors may have handles to objfiles.  Since their
+       storage has just been released, we'd better wipe the solib
+       descriptors as well.
+     */
+#if defined(SOLIB_RESTART)
+    SOLIB_RESTART ();
+#endif
+
+    symfile_objfile = NULL;
+    if (from_tty)
+      printf_unfiltered ("No symbol file now.\n");
+#ifdef HPUXHPPA
+    RESET_HP_UX_GLOBALS ();
+#endif
+}
+
+/* This is the symbol-file command.  Read the file, analyze its
+   symbols, and add a struct symtab to a symtab list.  The syntax of
+   the command is rather bizarre--(1) buildargv implements various
+   quoting conventions which are undocumented and have little or
+   nothing in common with the way things are quoted (or not quoted)
+   elsewhere in GDB, (2) options are used, which are not generally
+   used in GDB (perhaps "set mapped on", "set readnow on" would be
+   better), (3) the order of options matters, which is contrary to GNU
+   conventions (because it is confusing and inconvenient).  */
+/* Note: ezannoni 2000-04-17. This function used to have support for
+   rombug (see remote-os9k.c). It consisted of a call to target_link()
+   (target.c) to get the address of the text segment from the target,
+   and pass that to symbol_file_add(). This is no longer supported. */
+
+void
+symbol_file_command (char *args, int from_tty)
+{
+  char **argv;
+  char *name = NULL;
+  struct cleanup *cleanups;
+  int flags = OBJF_USERLOADED;
+
+  dont_repeat ();
+
+  if (args == NULL)
+    {
+      symbol_file_clear (from_tty);
+    }
+  else
+    {
+      if ((argv = buildargv (args)) == NULL)
+       {
+         nomem (0);
+       }
+      cleanups = make_cleanup_freeargv (argv);
+      while (*argv != NULL)
+       {
+         if (STREQ (*argv, "-mapped"))
+           flags |= OBJF_MAPPED;
+         else 
+           if (STREQ (*argv, "-readnow"))
+             flags |= OBJF_READNOW;
+           else 
+             if (**argv == '-')
+               error ("unknown option `%s'", *argv);
+             else
+               {
+                  name = *argv;
+
+                 symbol_file_add_main_1 (name, from_tty, flags);
+               }
+         argv++;
+       }
+
+      if (name == NULL)
+       {
+         error ("no symbol file name was specified");
+       }
+      do_cleanups (cleanups);
+    }
+}
+
+/* Set the initial language.
+
+   A better solution would be to record the language in the psymtab when reading
+   partial symbols, and then use it (if known) to set the language.  This would
+   be a win for formats that encode the language in an easily discoverable place,
+   such as DWARF.  For stabs, we can jump through hoops looking for specially
+   named symbols or try to intuit the language from the specific type of stabs
+   we find, but we can't do that until later when we read in full symbols.
+   FIXME.  */
+
+static void
+set_initial_language (void)
+{
+  struct partial_symtab *pst;
+  enum language lang = language_unknown;
+
+  pst = find_main_psymtab ();
+  if (pst != NULL)
+    {
+      if (pst->filename != NULL)
+       {
+         lang = deduce_language_from_filename (pst->filename);
+       }
+      if (lang == language_unknown)
+       {
+         /* Make C the default language */
+         lang = language_c;
+       }
+      set_language (lang);
+      expected_language = current_language;    /* Don't warn the user */
+    }
+}
+
+/* Open file specified by NAME and hand it off to BFD for preliminary
+   analysis.  Result is a newly initialized bfd *, which includes a newly
+   malloc'd` copy of NAME (tilde-expanded and made absolute).
+   In case of trouble, error() is called.  */
+
+bfd *
+symfile_bfd_open (char *name)
+{
+  bfd *sym_bfd;
+  int desc;
+  char *absolute_name;
+
+
+
+  name = tilde_expand (name);  /* Returns 1st new malloc'd copy */
+
+  /* Look down path for it, allocate 2nd new malloc'd copy.  */
+  desc = openp (getenv ("PATH"), 1, name, O_RDONLY | O_BINARY, 0, &absolute_name);
+#if defined(__GO32__) || defined(_WIN32) || defined (__CYGWIN__)
+  if (desc < 0)
+    {
+      char *exename = alloca (strlen (name) + 5);
+      strcat (strcpy (exename, name), ".exe");
+      desc = openp (getenv ("PATH"), 1, exename, O_RDONLY | O_BINARY,
+                   0, &absolute_name);
+    }
+#endif
+  if (desc < 0)
+    {
+      make_cleanup (xfree, name);
+      perror_with_name (name);
+    }
+  xfree (name);                        /* Free 1st new malloc'd copy */
+  name = absolute_name;                /* Keep 2nd malloc'd copy in bfd */
+  /* It'll be freed in free_objfile(). */
+
+  sym_bfd = bfd_fdopenr (name, gnutarget, desc);
+  if (!sym_bfd)
+    {
+      close (desc);
+      make_cleanup (xfree, name);
+      error ("\"%s\": can't open to read symbols: %s.", name,
+            bfd_errmsg (bfd_get_error ()));
+    }
+  sym_bfd->cacheable = 1;
+
+  if (!bfd_check_format (sym_bfd, bfd_object))
+    {
+      /* FIXME: should be checking for errors from bfd_close (for one thing,
+         on error it does not free all the storage associated with the
+         bfd).  */
+      bfd_close (sym_bfd);     /* This also closes desc */
+      make_cleanup (xfree, name);
+      error ("\"%s\": can't read symbols: %s.", name,
+            bfd_errmsg (bfd_get_error ()));
+    }
+  return (sym_bfd);
+}
+
+/* Return the section index for the given section name. Return -1 if
+   the section was not found. */
+int
+get_section_index (struct objfile *objfile, char *section_name)
+{
+  asection *sect = bfd_get_section_by_name (objfile->obfd, section_name);
+  if (sect)
+    return sect->index;
+  else
+    return -1;
+}
+
+/* Link a new symtab_fns into the global symtab_fns list.  Called on gdb
+   startup by the _initialize routine in each object file format reader,
+   to register information about each format the the reader is prepared
+   to handle. */
+
+void
+add_symtab_fns (struct sym_fns *sf)
+{
+  sf->next = symtab_fns;
+  symtab_fns = sf;
+}
+
+
+/* Initialize to read symbols from the symbol file sym_bfd.  It either
+   returns or calls error().  The result is an initialized struct sym_fns
+   in the objfile structure, that contains cached information about the
+   symbol file.  */
+
+static void
+find_sym_fns (struct objfile *objfile)
+{
+  struct sym_fns *sf;
+  enum bfd_flavour our_flavour = bfd_get_flavour (objfile->obfd);
+  char *our_target = bfd_get_target (objfile->obfd);
+
+  if (our_flavour == bfd_target_srec_flavour
+      || our_flavour == bfd_target_ihex_flavour
+      || our_flavour == bfd_target_tekhex_flavour)
+    return;    /* No symbols. */
+
+  /* Special kludge for apollo.  See dstread.c.  */
+  if (STREQN (our_target, "apollo", 6))
+    our_flavour = (enum bfd_flavour) -2;
+
+  for (sf = symtab_fns; sf != NULL; sf = sf->next)
+    {
+      if (our_flavour == sf->sym_flavour)
+       {
+         objfile->sf = sf;
+         return;
+       }
+    }
+  error ("I'm sorry, Dave, I can't do that.  Symbol format `%s' unknown.",
+        bfd_get_target (objfile->obfd));
+}
+\f
+/* This function runs the load command of our current target.  */
+
+static void
+load_command (char *arg, int from_tty)
+{
+  if (arg == NULL)
+    arg = get_exec_file (1);
+  target_load (arg, from_tty);
+
+  /* After re-loading the executable, we don't really know which
+     overlays are mapped any more.  */
+  overlay_cache_invalid = 1;
+}
+
+/* This version of "load" should be usable for any target.  Currently
+   it is just used for remote targets, not inftarg.c or core files,
+   on the theory that only in that case is it useful.
+
+   Avoiding xmodem and the like seems like a win (a) because we don't have
+   to worry about finding it, and (b) On VMS, fork() is very slow and so
+   we don't want to run a subprocess.  On the other hand, I'm not sure how
+   performance compares.  */
+
+static int download_write_size = 512;
+static int validate_download = 0;
+
+/* Callback service function for generic_load (bfd_map_over_sections).  */
+
+static void
+add_section_size_callback (bfd *abfd, asection *asec, void *data)
+{
+  bfd_size_type *sum = data;
+
+  *sum += bfd_get_section_size_before_reloc (asec);
+}
+
+/* Opaque data for load_section_callback.  */
+struct load_section_data {
+  unsigned long load_offset;
+  unsigned long write_count;
+  unsigned long data_count;
+  bfd_size_type total_size;
+};
+
+/* Callback service function for generic_load (bfd_map_over_sections).  */
+
+static void
+load_section_callback (bfd *abfd, asection *asec, void *data)
+{
+  struct load_section_data *args = data;
+
+  if (bfd_get_section_flags (abfd, asec) & SEC_LOAD)
+    {
+      bfd_size_type size = bfd_get_section_size_before_reloc (asec);
+      if (size > 0)
+       {
+         char *buffer;
+         struct cleanup *old_chain;
+         CORE_ADDR lma = bfd_section_lma (abfd, asec) + args->load_offset;
+         bfd_size_type block_size;
+         int err;
+         const char *sect_name = bfd_get_section_name (abfd, asec);
+         bfd_size_type sent;
+
+         if (download_write_size > 0 && size > download_write_size)
+           block_size = download_write_size;
+         else
+           block_size = size;
+
+         buffer = xmalloc (size);
+         old_chain = make_cleanup (xfree, buffer);
+
+         /* Is this really necessary?  I guess it gives the user something
+            to look at during a long download.  */
+         ui_out_message (uiout, 0, "Loading section %s, size 0x%s lma 0x%s\n",
+                         sect_name, paddr_nz (size), paddr_nz (lma));
+
+         bfd_get_section_contents (abfd, asec, buffer, 0, size);
+
+         sent = 0;
+         do
+           {
+             int len;
+             bfd_size_type this_transfer = size - sent;
+
+             if (this_transfer >= block_size)
+               this_transfer = block_size;
+             len = target_write_memory_partial (lma, buffer,
+                                                this_transfer, &err);
+             if (err)
+               break;
+             if (validate_download)
+               {
+                 /* Broken memories and broken monitors manifest
+                    themselves here when bring new computers to
+                    life.  This doubles already slow downloads.  */
+                 /* NOTE: cagney/1999-10-18: A more efficient
+                    implementation might add a verify_memory()
+                    method to the target vector and then use
+                    that.  remote.c could implement that method
+                    using the ``qCRC'' packet.  */
+                 char *check = xmalloc (len);
+                 struct cleanup *verify_cleanups = 
+                   make_cleanup (xfree, check);
+
+                 if (target_read_memory (lma, check, len) != 0)
+                   error ("Download verify read failed at 0x%s",
+                          paddr (lma));
+                 if (memcmp (buffer, check, len) != 0)
+                   error ("Download verify compare failed at 0x%s",
+                          paddr (lma));
+                 do_cleanups (verify_cleanups);
+               }
+             args->data_count += len;
+             lma += len;
+             buffer += len;
+             args->write_count += 1;
+             sent += len;
+             if (quit_flag
+                 || (ui_load_progress_hook != NULL
+                     && ui_load_progress_hook (sect_name, sent)))
+               error ("Canceled the download");
+
+             if (show_load_progress != NULL)
+               show_load_progress (sect_name, sent, size, 
+                                   args->data_count, args->total_size);
+           }
+         while (sent < size);
+
+         if (err != 0)
+           error ("Memory access error while loading section %s.", sect_name);
+
+         do_cleanups (old_chain);
+       }
+    }
+}
+
+void
+generic_load (char *args, int from_tty)
+{
+  asection *s;
+  bfd *loadfile_bfd;
+  time_t start_time, end_time; /* Start and end times of download */
+  char *filename;
+  struct cleanup *old_cleanups;
+  char *offptr;
+  struct load_section_data cbdata;
+  CORE_ADDR entry;
+
+  cbdata.load_offset = 0;      /* Offset to add to vma for each section. */
+  cbdata.write_count = 0;      /* Number of writes needed. */
+  cbdata.data_count = 0;       /* Number of bytes written to target memory. */
+  cbdata.total_size = 0;       /* Total size of all bfd sectors. */
+
+  /* Parse the input argument - the user can specify a load offset as
+     a second argument. */
+  filename = xmalloc (strlen (args) + 1);
+  old_cleanups = make_cleanup (xfree, filename);
+  strcpy (filename, args);
+  offptr = strchr (filename, ' ');
+  if (offptr != NULL)
+    {
+      char *endptr;
+
+      cbdata.load_offset = strtoul (offptr, &endptr, 0);
+      if (offptr == endptr)
+       error ("Invalid download offset:%s\n", offptr);
+      *offptr = '\0';
+    }
+  else
+    cbdata.load_offset = 0;
+
+  /* Open the file for loading. */
+  loadfile_bfd = bfd_openr (filename, gnutarget);
+  if (loadfile_bfd == NULL)
+    {
+      perror_with_name (filename);
+      return;
+    }
+
+  /* FIXME: should be checking for errors from bfd_close (for one thing,
+     on error it does not free all the storage associated with the
+     bfd).  */
+  make_cleanup_bfd_close (loadfile_bfd);
+
+  if (!bfd_check_format (loadfile_bfd, bfd_object))
+    {
+      error ("\"%s\" is not an object file: %s", filename,
+            bfd_errmsg (bfd_get_error ()));
+    }
+
+  bfd_map_over_sections (loadfile_bfd, add_section_size_callback, 
+                        (void *) &cbdata.total_size);
+
+  start_time = time (NULL);
+
+  bfd_map_over_sections (loadfile_bfd, load_section_callback, &cbdata);
+
+  end_time = time (NULL);
+
+  entry = bfd_get_start_address (loadfile_bfd);
+  ui_out_text (uiout, "Start address ");
+  ui_out_field_fmt (uiout, "address", "0x%s", paddr_nz (entry));
+  ui_out_text (uiout, ", load size ");
+  ui_out_field_fmt (uiout, "load-size", "%lu", cbdata.data_count);
+  ui_out_text (uiout, "\n");
+  /* We were doing this in remote-mips.c, I suspect it is right
+     for other targets too.  */
+  write_pc (entry);
+
+  /* FIXME: are we supposed to call symbol_file_add or not?  According to
+     a comment from remote-mips.c (where a call to symbol_file_add was
+     commented out), making the call confuses GDB if more than one file is
+     loaded in.  remote-nindy.c had no call to symbol_file_add, but remote-vx.c
+     does.  */
+
+  print_transfer_performance (gdb_stdout, cbdata.data_count, 
+                             cbdata.write_count, end_time - start_time);
+
+  do_cleanups (old_cleanups);
+}
+
+/* Report how fast the transfer went. */
+
+/* DEPRECATED: cagney/1999-10-18: report_transfer_performance is being
+   replaced by print_transfer_performance (with a very different
+   function signature). */
+
+void
+report_transfer_performance (unsigned long data_count, time_t start_time,
+                            time_t end_time)
+{
+  print_transfer_performance (gdb_stdout, data_count, 
+                             end_time - start_time, 0);
+}
+
+void
+print_transfer_performance (struct ui_file *stream,
+                           unsigned long data_count,
+                           unsigned long write_count,
+                           unsigned long time_count)
+{
+  ui_out_text (uiout, "Transfer rate: ");
+  if (time_count > 0)
+    {
+      ui_out_field_fmt (uiout, "transfer-rate", "%lu", 
+                       (data_count * 8) / time_count);
+      ui_out_text (uiout, " bits/sec");
+    }
+  else
+    {
+      ui_out_field_fmt (uiout, "transferred-bits", "%lu", (data_count * 8));
+      ui_out_text (uiout, " bits in <1 sec");    
+    }
+  if (write_count > 0)
+    {
+      ui_out_text (uiout, ", ");
+      ui_out_field_fmt (uiout, "write-rate", "%lu", data_count / write_count);
+      ui_out_text (uiout, " bytes/write");
+    }
+  ui_out_text (uiout, ".\n");
+}
+
+/* This function allows the addition of incrementally linked object files.
+   It does not modify any state in the target, only in the debugger.  */
+/* Note: ezannoni 2000-04-13 This function/command used to have a
+   special case syntax for the rombug target (Rombug is the boot
+   monitor for Microware's OS-9 / OS-9000, see remote-os9k.c). In the
+   rombug case, the user doesn't need to supply a text address,
+   instead a call to target_link() (in target.c) would supply the
+   value to use. We are now discontinuing this type of ad hoc syntax. */
+
+/* ARGSUSED */
+static void
+add_symbol_file_command (char *args, int from_tty)
+{
+  char *filename = NULL;
+  int flags = OBJF_USERLOADED;
+  char *arg;
+  int expecting_option = 0;
+  int section_index = 0;
+  int argcnt = 0;
+  int sec_num = 0;
+  int i;
+  int expecting_sec_name = 0;
+  int expecting_sec_addr = 0;
+
+  struct
+  {
+    char *name;
+    char *value;
+  } sect_opts[SECT_OFF_MAX];
+
+  struct section_addr_info section_addrs;
+  struct cleanup *my_cleanups = make_cleanup (null_cleanup, NULL);
+
+  dont_repeat ();
+
+  if (args == NULL)
+    error ("add-symbol-file takes a file name and an address");
+
+  /* Make a copy of the string that we can safely write into. */
+  args = xstrdup (args);
+
+  /* Ensure section_addrs is initialized */
+  memset (&section_addrs, 0, sizeof (section_addrs));
+
+  while (*args != '\000')
+    {
+      /* Any leading spaces? */
+      while (isspace (*args))
+       args++;
+
+      /* Point arg to the beginning of the argument. */
+      arg = args;
+
+      /* Move args pointer over the argument. */
+      while ((*args != '\000') && !isspace (*args))
+       args++;
+
+      /* If there are more arguments, terminate arg and
+         proceed past it. */
+      if (*args != '\000')
+       *args++ = '\000';
+
+      /* Now process the argument. */
+      if (argcnt == 0)
+       {
+         /* The first argument is the file name. */
+         filename = tilde_expand (arg);
+         make_cleanup (xfree, filename);
+       }
+      else
+       if (argcnt == 1)
+         {
+           /* The second argument is always the text address at which
+               to load the program. */
+           sect_opts[section_index].name = ".text";
+           sect_opts[section_index].value = arg;
+           section_index++;              
+         }
+       else
+         {
+           /* It's an option (starting with '-') or it's an argument
+              to an option */
+
+           if (*arg == '-')
+             {
+               if (strcmp (arg, "-mapped") == 0)
+                 flags |= OBJF_MAPPED;
+               else 
+                 if (strcmp (arg, "-readnow") == 0)
+                   flags |= OBJF_READNOW;
+                 else 
+                   if (strcmp (arg, "-s") == 0)
+                     {
+                       if (section_index >= SECT_OFF_MAX)
+                         error ("Too many sections specified.");
+                       expecting_sec_name = 1;
+                       expecting_sec_addr = 1;
+                     }
+             }
+           else
+             {
+               if (expecting_sec_name)
+                 {
+                   sect_opts[section_index].name = arg;
+                   expecting_sec_name = 0;
+                 }
+               else
+                 if (expecting_sec_addr)
+                   {
+                     sect_opts[section_index].value = arg;
+                     expecting_sec_addr = 0;
+                     section_index++;            
+                   }
+                 else
+                   error ("USAGE: add-symbol-file <filename> <textaddress> [-mapped] [-readnow] [-s <secname> <addr>]*");
+             }
+         }
+      argcnt++;
+    }
+
+  /* Print the prompt for the query below. And save the arguments into
+     a sect_addr_info structure to be passed around to other
+     functions.  We have to split this up into separate print
+     statements because local_hex_string returns a local static
+     string. */
+  printf_filtered ("add symbol table from file \"%s\" at\n", filename);
+  for (i = 0; i < section_index; i++)
+    {
+      CORE_ADDR addr;
+      char *val = sect_opts[i].value;
+      char *sec = sect_opts[i].name;
+      val = sect_opts[i].value;
+      if (val[0] == '0' && val[1] == 'x')
+       addr = strtoul (val+2, NULL, 16);
+      else
+       addr = strtoul (val, NULL, 10);
+
+      /* Here we store the section offsets in the order they were
+         entered on the command line. */
+      section_addrs.other[sec_num].name = sec;
+      section_addrs.other[sec_num].addr = addr;
+      printf_filtered ("\t%s_addr = %s\n",
+                      sec, 
+                      local_hex_string ((unsigned long)addr));
+      sec_num++;
+
+      /* The object's sections are initialized when a 
+        call is made to build_objfile_section_table (objfile).
+        This happens in reread_symbols. 
+        At this point, we don't know what file type this is,
+        so we can't determine what section names are valid.  */
+    }
+
+  if (from_tty && (!query ("%s", "")))
+    error ("Not confirmed.");
+
+  symbol_file_add (filename, from_tty, &section_addrs, 0, flags);
+
+  /* Getting new symbols may change our opinion about what is
+     frameless.  */
+  reinit_frame_cache ();
+  do_cleanups (my_cleanups);
+}
+\f
+static void
+add_shared_symbol_files_command (char *args, int from_tty)
+{
+#ifdef ADD_SHARED_SYMBOL_FILES
+  ADD_SHARED_SYMBOL_FILES (args, from_tty);
+#else
+  error ("This command is not available in this configuration of GDB.");
+#endif
+}
+\f
+/* Re-read symbols if a symbol-file has changed.  */
+void
+reread_symbols (void)
+{
+  struct objfile *objfile;
+  long new_modtime;
+  int reread_one = 0;
+  struct stat new_statbuf;
+  int res;
+
+  /* With the addition of shared libraries, this should be modified,
+     the load time should be saved in the partial symbol tables, since
+     different tables may come from different source files.  FIXME.
+     This routine should then walk down each partial symbol table
+     and see if the symbol table that it originates from has been changed */
+
+  for (objfile = object_files; objfile; objfile = objfile->next)
+    {
+      if (objfile->obfd)
+       {
+#ifdef IBM6000_TARGET
+         /* If this object is from a shared library, then you should
+            stat on the library name, not member name. */
+
+         if (objfile->obfd->my_archive)
+           res = stat (objfile->obfd->my_archive->filename, &new_statbuf);
+         else
+#endif
+           res = stat (objfile->name, &new_statbuf);
+         if (res != 0)
+           {
+             /* FIXME, should use print_sys_errmsg but it's not filtered. */
+             printf_filtered ("`%s' has disappeared; keeping its symbols.\n",
+                              objfile->name);
+             continue;
+           }
+         new_modtime = new_statbuf.st_mtime;
+         if (new_modtime != objfile->mtime)
+           {
+             struct cleanup *old_cleanups;
+             struct section_offsets *offsets;
+             int num_offsets;
+             char *obfd_filename;
+
+             printf_filtered ("`%s' has changed; re-reading symbols.\n",
+                              objfile->name);
+
+             /* There are various functions like symbol_file_add,
+                symfile_bfd_open, syms_from_objfile, etc., which might
+                appear to do what we want.  But they have various other
+                effects which we *don't* want.  So we just do stuff
+                ourselves.  We don't worry about mapped files (for one thing,
+                any mapped file will be out of date).  */
+
+             /* If we get an error, blow away this objfile (not sure if
+                that is the correct response for things like shared
+                libraries).  */
+             old_cleanups = make_cleanup_free_objfile (objfile);
+             /* We need to do this whenever any symbols go away.  */
+             make_cleanup (clear_symtab_users_cleanup, 0 /*ignore*/);
+
+             /* Clean up any state BFD has sitting around.  We don't need
+                to close the descriptor but BFD lacks a way of closing the
+                BFD without closing the descriptor.  */
+             obfd_filename = bfd_get_filename (objfile->obfd);
+             if (!bfd_close (objfile->obfd))
+               error ("Can't close BFD for %s: %s", objfile->name,
+                      bfd_errmsg (bfd_get_error ()));
+             objfile->obfd = bfd_openr (obfd_filename, gnutarget);
+             if (objfile->obfd == NULL)
+               error ("Can't open %s to read symbols.", objfile->name);
+             /* bfd_openr sets cacheable to true, which is what we want.  */
+             if (!bfd_check_format (objfile->obfd, bfd_object))
+               error ("Can't read symbols from %s: %s.", objfile->name,
+                      bfd_errmsg (bfd_get_error ()));
+
+             /* Save the offsets, we will nuke them with the rest of the
+                psymbol_obstack.  */
+             num_offsets = objfile->num_sections;
+             offsets = (struct section_offsets *) alloca (SIZEOF_SECTION_OFFSETS);
+             memcpy (offsets, objfile->section_offsets, SIZEOF_SECTION_OFFSETS);
+
+             /* Nuke all the state that we will re-read.  Much of the following
+                code which sets things to NULL really is necessary to tell
+                other parts of GDB that there is nothing currently there.  */
+
+             /* FIXME: Do we have to free a whole linked list, or is this
+                enough?  */
+             if (objfile->global_psymbols.list)
+               xmfree (objfile->md, objfile->global_psymbols.list);
+             memset (&objfile->global_psymbols, 0,
+                     sizeof (objfile->global_psymbols));
+             if (objfile->static_psymbols.list)
+               xmfree (objfile->md, objfile->static_psymbols.list);
+             memset (&objfile->static_psymbols, 0,
+                     sizeof (objfile->static_psymbols));
+
+             /* Free the obstacks for non-reusable objfiles */
+             bcache_xfree (objfile->psymbol_cache);
+             objfile->psymbol_cache = bcache_xmalloc ();
+             bcache_xfree (objfile->macro_cache);
+             objfile->macro_cache = bcache_xmalloc ();
+             obstack_free (&objfile->psymbol_obstack, 0);
+             obstack_free (&objfile->symbol_obstack, 0);
+             obstack_free (&objfile->type_obstack, 0);
+             objfile->sections = NULL;
+             objfile->symtabs = NULL;
+             objfile->psymtabs = NULL;
+             objfile->free_psymtabs = NULL;
+             objfile->msymbols = NULL;
+             objfile->minimal_symbol_count = 0;
+             memset (&objfile->msymbol_hash, 0,
+                     sizeof (objfile->msymbol_hash));
+             memset (&objfile->msymbol_demangled_hash, 0,
+                     sizeof (objfile->msymbol_demangled_hash));
+             objfile->fundamental_types = NULL;
+             if (objfile->sf != NULL)
+               {
+                 (*objfile->sf->sym_finish) (objfile);
+               }
+
+             /* We never make this a mapped file.  */
+             objfile->md = NULL;
+             /* obstack_specify_allocation also initializes the obstack so
+                it is empty.  */
+             objfile->psymbol_cache = bcache_xmalloc ();
+             objfile->macro_cache = bcache_xmalloc ();
+             obstack_specify_allocation (&objfile->psymbol_obstack, 0, 0,
+                                         xmalloc, xfree);
+             obstack_specify_allocation (&objfile->symbol_obstack, 0, 0,
+                                         xmalloc, xfree);
+             obstack_specify_allocation (&objfile->type_obstack, 0, 0,
+                                         xmalloc, xfree);
+             if (build_objfile_section_table (objfile))
+               {
+                 error ("Can't find the file sections in `%s': %s",
+                        objfile->name, bfd_errmsg (bfd_get_error ()));
+               }
+
+             /* We use the same section offsets as from last time.  I'm not
+                sure whether that is always correct for shared libraries.  */
+             objfile->section_offsets = (struct section_offsets *)
+               obstack_alloc (&objfile->psymbol_obstack, SIZEOF_SECTION_OFFSETS);
+             memcpy (objfile->section_offsets, offsets, SIZEOF_SECTION_OFFSETS);
+             objfile->num_sections = num_offsets;
+
+             /* What the hell is sym_new_init for, anyway?  The concept of
+                distinguishing between the main file and additional files
+                in this way seems rather dubious.  */
+             if (objfile == symfile_objfile)
+               {
+                 (*objfile->sf->sym_new_init) (objfile);
+#ifdef HPUXHPPA
+                 RESET_HP_UX_GLOBALS ();
+#endif
+               }
+
+             (*objfile->sf->sym_init) (objfile);
+             clear_complaints (&symfile_complaints, 1, 1);
+             /* The "mainline" parameter is a hideous hack; I think leaving it
+                zero is OK since dbxread.c also does what it needs to do if
+                objfile->global_psymbols.size is 0.  */
+             (*objfile->sf->sym_read) (objfile, 0);
+             if (!have_partial_symbols () && !have_full_symbols ())
+               {
+                 wrap_here ("");
+                 printf_filtered ("(no debugging symbols found)\n");
+                 wrap_here ("");
+               }
+             objfile->flags |= OBJF_SYMS;
+
+             /* We're done reading the symbol file; finish off complaints.  */
+             clear_complaints (&symfile_complaints, 0, 1);
+
+             /* Getting new symbols may change our opinion about what is
+                frameless.  */
+
+             reinit_frame_cache ();
+
+             /* Discard cleanups as symbol reading was successful.  */
+             discard_cleanups (old_cleanups);
+
+             /* If the mtime has changed between the time we set new_modtime
+                and now, we *want* this to be out of date, so don't call stat
+                again now.  */
+             objfile->mtime = new_modtime;
+             reread_one = 1;
+
+             /* Call this after reading in a new symbol table to give target
+                dependent code a crack at the new symbols.  For instance, this
+                could be used to update the values of target-specific symbols GDB
+                needs to keep track of (such as _sigtramp, or whatever).  */
+
+             TARGET_SYMFILE_POSTREAD (objfile);
+           }
+       }
+    }
+
+  if (reread_one)
+    clear_symtab_users ();
+}
+\f
+
+
+typedef struct
+{
+  char *ext;
+  enum language lang;
+}
+filename_language;
+
+static filename_language *filename_language_table;
+static int fl_table_size, fl_table_next;
+
+static void
+add_filename_language (char *ext, enum language lang)
+{
+  if (fl_table_next >= fl_table_size)
+    {
+      fl_table_size += 10;
+      filename_language_table = 
+       xrealloc (filename_language_table,
+                 fl_table_size * sizeof (*filename_language_table));
+    }
+
+  filename_language_table[fl_table_next].ext = xstrdup (ext);
+  filename_language_table[fl_table_next].lang = lang;
+  fl_table_next++;
+}
+
+static char *ext_args;
+
+static void
+set_ext_lang_command (char *args, int from_tty)
+{
+  int i;
+  char *cp = ext_args;
+  enum language lang;
+
+  /* First arg is filename extension, starting with '.' */
+  if (*cp != '.')
+    error ("'%s': Filename extension must begin with '.'", ext_args);
+
+  /* Find end of first arg.  */
+  while (*cp && !isspace (*cp))
+    cp++;
+
+  if (*cp == '\0')
+    error ("'%s': two arguments required -- filename extension and language",
+          ext_args);
+
+  /* Null-terminate first arg */
+  *cp++ = '\0';
+
+  /* Find beginning of second arg, which should be a source language.  */
+  while (*cp && isspace (*cp))
+    cp++;
+
+  if (*cp == '\0')
+    error ("'%s': two arguments required -- filename extension and language",
+          ext_args);
+
+  /* Lookup the language from among those we know.  */
+  lang = language_enum (cp);
+
+  /* Now lookup the filename extension: do we already know it?  */
+  for (i = 0; i < fl_table_next; i++)
+    if (0 == strcmp (ext_args, filename_language_table[i].ext))
+      break;
+
+  if (i >= fl_table_next)
+    {
+      /* new file extension */
+      add_filename_language (ext_args, lang);
+    }
+  else
+    {
+      /* redefining a previously known filename extension */
+
+      /* if (from_tty) */
+      /*   query ("Really make files of type %s '%s'?", */
+      /*          ext_args, language_str (lang));           */
+
+      xfree (filename_language_table[i].ext);
+      filename_language_table[i].ext = xstrdup (ext_args);
+      filename_language_table[i].lang = lang;
+    }
+}
+
+static void
+info_ext_lang_command (char *args, int from_tty)
+{
+  int i;
+
+  printf_filtered ("Filename extensions and the languages they represent:");
+  printf_filtered ("\n\n");
+  for (i = 0; i < fl_table_next; i++)
+    printf_filtered ("\t%s\t- %s\n",
+                    filename_language_table[i].ext,
+                    language_str (filename_language_table[i].lang));
+}
+
+static void
+init_filename_language_table (void)
+{
+  if (fl_table_size == 0)      /* protect against repetition */
+    {
+      fl_table_size = 20;
+      fl_table_next = 0;
+      filename_language_table =
+       xmalloc (fl_table_size * sizeof (*filename_language_table));
+      add_filename_language (".c", language_c);
+      add_filename_language (".C", language_cplus);
+      add_filename_language (".cc", language_cplus);
+      add_filename_language (".cp", language_cplus);
+      add_filename_language (".cpp", language_cplus);
+      add_filename_language (".cxx", language_cplus);
+      add_filename_language (".c++", language_cplus);
+      add_filename_language (".java", language_java);
+      add_filename_language (".class", language_java);
+      /* OBSOLETE add_filename_language (".ch", language_chill); */
+      /* OBSOLETE add_filename_language (".c186", language_chill); */
+      /* OBSOLETE add_filename_language (".c286", language_chill); */
+      add_filename_language (".f", language_fortran);
+      add_filename_language (".F", language_fortran);
+      add_filename_language (".s", language_asm);
+      add_filename_language (".S", language_asm);
+      add_filename_language (".pas", language_pascal);
+      add_filename_language (".p", language_pascal);
+      add_filename_language (".pp", language_pascal);
+    }
+}
+
+enum language
+deduce_language_from_filename (char *filename)
+{
+  int i;
+  char *cp;
+
+  if (filename != NULL)
+    if ((cp = strrchr (filename, '.')) != NULL)
+      for (i = 0; i < fl_table_next; i++)
+       if (strcmp (cp, filename_language_table[i].ext) == 0)
+         return filename_language_table[i].lang;
+
+  return language_unknown;
+}
+\f
+/* allocate_symtab:
+
+   Allocate and partly initialize a new symbol table.  Return a pointer
+   to it.  error() if no space.
+
+   Caller must set these fields:
+   LINETABLE(symtab)
+   symtab->blockvector
+   symtab->dirname
+   symtab->free_code
+   symtab->free_ptr
+   possibly free_named_symtabs (symtab->filename);
+ */
+
+struct symtab *
+allocate_symtab (char *filename, struct objfile *objfile)
+{
+  register struct symtab *symtab;
+
+  symtab = (struct symtab *)
+    obstack_alloc (&objfile->symbol_obstack, sizeof (struct symtab));
+  memset (symtab, 0, sizeof (*symtab));
+  symtab->filename = obsavestring (filename, strlen (filename),
+                                  &objfile->symbol_obstack);
+  symtab->fullname = NULL;
+  symtab->language = deduce_language_from_filename (filename);
+  symtab->debugformat = obsavestring ("unknown", 7,
+                                     &objfile->symbol_obstack);
+
+  /* Hook it to the objfile it comes from */
+
+  symtab->objfile = objfile;
+  symtab->next = objfile->symtabs;
+  objfile->symtabs = symtab;
+
+  /* FIXME: This should go away.  It is only defined for the Z8000,
+     and the Z8000 definition of this macro doesn't have anything to
+     do with the now-nonexistent EXTRA_SYMTAB_INFO macro, it's just
+     here for convenience.  */
+#ifdef INIT_EXTRA_SYMTAB_INFO
+  INIT_EXTRA_SYMTAB_INFO (symtab);
+#endif
+
+  return (symtab);
+}
+
+struct partial_symtab *
+allocate_psymtab (char *filename, struct objfile *objfile)
+{
+  struct partial_symtab *psymtab;
+
+  if (objfile->free_psymtabs)
+    {
+      psymtab = objfile->free_psymtabs;
+      objfile->free_psymtabs = psymtab->next;
+    }
+  else
+    psymtab = (struct partial_symtab *)
+      obstack_alloc (&objfile->psymbol_obstack,
+                    sizeof (struct partial_symtab));
+
+  memset (psymtab, 0, sizeof (struct partial_symtab));
+  psymtab->filename = obsavestring (filename, strlen (filename),
+                                   &objfile->psymbol_obstack);
+  psymtab->symtab = NULL;
+
+  /* Prepend it to the psymtab list for the objfile it belongs to.
+     Psymtabs are searched in most recent inserted -> least recent
+     inserted order. */
+
+  psymtab->objfile = objfile;
+  psymtab->next = objfile->psymtabs;
+  objfile->psymtabs = psymtab;
+#if 0
+  {
+    struct partial_symtab **prev_pst;
+    psymtab->objfile = objfile;
+    psymtab->next = NULL;
+    prev_pst = &(objfile->psymtabs);
+    while ((*prev_pst) != NULL)
+      prev_pst = &((*prev_pst)->next);
+    (*prev_pst) = psymtab;
+  }
+#endif
+
+  return (psymtab);
+}
+
+void
+discard_psymtab (struct partial_symtab *pst)
+{
+  struct partial_symtab **prev_pst;
+
+  /* From dbxread.c:
+     Empty psymtabs happen as a result of header files which don't
+     have any symbols in them.  There can be a lot of them.  But this
+     check is wrong, in that a psymtab with N_SLINE entries but
+     nothing else is not empty, but we don't realize that.  Fixing
+     that without slowing things down might be tricky.  */
+
+  /* First, snip it out of the psymtab chain */
+
+  prev_pst = &(pst->objfile->psymtabs);
+  while ((*prev_pst) != pst)
+    prev_pst = &((*prev_pst)->next);
+  (*prev_pst) = pst->next;
+
+  /* Next, put it on a free list for recycling */
+
+  pst->next = pst->objfile->free_psymtabs;
+  pst->objfile->free_psymtabs = pst;
+}
+\f
+
+/* Reset all data structures in gdb which may contain references to symbol
+   table data.  */
+
+void
+clear_symtab_users (void)
+{
+  /* Someday, we should do better than this, by only blowing away
+     the things that really need to be blown.  */
+  clear_value_history ();
+  clear_displays ();
+  clear_internalvars ();
+  breakpoint_re_set ();
+  set_default_breakpoint (0, 0, 0, 0);
+  clear_current_source_symtab_and_line ();
+  clear_pc_function_cache ();
+  if (target_new_objfile_hook)
+    target_new_objfile_hook (NULL);
+}
+
+static void
+clear_symtab_users_cleanup (void *ignore)
+{
+  clear_symtab_users ();
+}
+
+/* clear_symtab_users_once:
+
+   This function is run after symbol reading, or from a cleanup.
+   If an old symbol table was obsoleted, the old symbol table
+   has been blown away, but the other GDB data structures that may 
+   reference it have not yet been cleared or re-directed.  (The old
+   symtab was zapped, and the cleanup queued, in free_named_symtab()
+   below.)
+
+   This function can be queued N times as a cleanup, or called
+   directly; it will do all the work the first time, and then will be a
+   no-op until the next time it is queued.  This works by bumping a
+   counter at queueing time.  Much later when the cleanup is run, or at
+   the end of symbol processing (in case the cleanup is discarded), if
+   the queued count is greater than the "done-count", we do the work
+   and set the done-count to the queued count.  If the queued count is
+   less than or equal to the done-count, we just ignore the call.  This
+   is needed because reading a single .o file will often replace many
+   symtabs (one per .h file, for example), and we don't want to reset
+   the breakpoints N times in the user's face.
+
+   The reason we both queue a cleanup, and call it directly after symbol
+   reading, is because the cleanup protects us in case of errors, but is
+   discarded if symbol reading is successful.  */
+
+#if 0
+/* FIXME:  As free_named_symtabs is currently a big noop this function
+   is no longer needed.  */
+static void clear_symtab_users_once (void);
+
+static int clear_symtab_users_queued;
+static int clear_symtab_users_done;
+
+static void
+clear_symtab_users_once (void)
+{
+  /* Enforce once-per-`do_cleanups'-semantics */
+  if (clear_symtab_users_queued <= clear_symtab_users_done)
+    return;
+  clear_symtab_users_done = clear_symtab_users_queued;
+
+  clear_symtab_users ();
+}
+#endif
+
+/* Delete the specified psymtab, and any others that reference it.  */
+
+static void
+cashier_psymtab (struct partial_symtab *pst)
+{
+  struct partial_symtab *ps, *pprev = NULL;
+  int i;
+
+  /* Find its previous psymtab in the chain */
+  for (ps = pst->objfile->psymtabs; ps; ps = ps->next)
+    {
+      if (ps == pst)
+       break;
+      pprev = ps;
+    }
+
+  if (ps)
+    {
+      /* Unhook it from the chain.  */
+      if (ps == pst->objfile->psymtabs)
+       pst->objfile->psymtabs = ps->next;
+      else
+       pprev->next = ps->next;
+
+      /* FIXME, we can't conveniently deallocate the entries in the
+         partial_symbol lists (global_psymbols/static_psymbols) that
+         this psymtab points to.  These just take up space until all
+         the psymtabs are reclaimed.  Ditto the dependencies list and
+         filename, which are all in the psymbol_obstack.  */
+
+      /* We need to cashier any psymtab that has this one as a dependency... */
+    again:
+      for (ps = pst->objfile->psymtabs; ps; ps = ps->next)
+       {
+         for (i = 0; i < ps->number_of_dependencies; i++)
+           {
+             if (ps->dependencies[i] == pst)
+               {
+                 cashier_psymtab (ps);
+                 goto again;   /* Must restart, chain has been munged. */
+               }
+           }
+       }
+    }
+}
+
+/* If a symtab or psymtab for filename NAME is found, free it along
+   with any dependent breakpoints, displays, etc.
+   Used when loading new versions of object modules with the "add-file"
+   command.  This is only called on the top-level symtab or psymtab's name;
+   it is not called for subsidiary files such as .h files.
+
+   Return value is 1 if we blew away the environment, 0 if not.
+   FIXME.  The return value appears to never be used.
+
+   FIXME.  I think this is not the best way to do this.  We should
+   work on being gentler to the environment while still cleaning up
+   all stray pointers into the freed symtab.  */
+
+int
+free_named_symtabs (char *name)
+{
+#if 0
+  /* FIXME:  With the new method of each objfile having it's own
+     psymtab list, this function needs serious rethinking.  In particular,
+     why was it ever necessary to toss psymtabs with specific compilation
+     unit filenames, as opposed to all psymtabs from a particular symbol
+     file?  -- fnf
+     Well, the answer is that some systems permit reloading of particular
+     compilation units.  We want to blow away any old info about these
+     compilation units, regardless of which objfiles they arrived in. --gnu.  */
+
+  register struct symtab *s;
+  register struct symtab *prev;
+  register struct partial_symtab *ps;
+  struct blockvector *bv;
+  int blewit = 0;
+
+  /* We only wack things if the symbol-reload switch is set.  */
+  if (!symbol_reloading)
+    return 0;
+
+  /* Some symbol formats have trouble providing file names... */
+  if (name == 0 || *name == '\0')
+    return 0;
+
+  /* Look for a psymtab with the specified name.  */
+
+again2:
+  for (ps = partial_symtab_list; ps; ps = ps->next)
+    {
+      if (STREQ (name, ps->filename))
+       {
+         cashier_psymtab (ps); /* Blow it away...and its little dog, too.  */
+         goto again2;          /* Must restart, chain has been munged */
+       }
+    }
+
+  /* Look for a symtab with the specified name.  */
+
+  for (s = symtab_list; s; s = s->next)
+    {
+      if (STREQ (name, s->filename))
+       break;
+      prev = s;
+    }
+
+  if (s)
+    {
+      if (s == symtab_list)
+       symtab_list = s->next;
+      else
+       prev->next = s->next;
+
+      /* For now, queue a delete for all breakpoints, displays, etc., whether
+         or not they depend on the symtab being freed.  This should be
+         changed so that only those data structures affected are deleted.  */
+
+      /* But don't delete anything if the symtab is empty.
+         This test is necessary due to a bug in "dbxread.c" that
+         causes empty symtabs to be created for N_SO symbols that
+         contain the pathname of the object file.  (This problem
+         has been fixed in GDB 3.9x).  */
+
+      bv = BLOCKVECTOR (s);
+      if (BLOCKVECTOR_NBLOCKS (bv) > 2
+         || BLOCK_NSYMS (BLOCKVECTOR_BLOCK (bv, GLOBAL_BLOCK))
+         || BLOCK_NSYMS (BLOCKVECTOR_BLOCK (bv, STATIC_BLOCK)))
+       {
+         complaint (&symfile_complaints, "Replacing old symbols for `%s'",
+                    name);
+         clear_symtab_users_queued++;
+         make_cleanup (clear_symtab_users_once, 0);
+         blewit = 1;
+       }
+      else
+       {
+         complaint (&symfile_complaints, "Empty symbol table found for `%s'",
+                    name);
+       }
+
+      free_symtab (s);
+    }
+  else
+    {
+      /* It is still possible that some breakpoints will be affected
+         even though no symtab was found, since the file might have
+         been compiled without debugging, and hence not be associated
+         with a symtab.  In order to handle this correctly, we would need
+         to keep a list of text address ranges for undebuggable files.
+         For now, we do nothing, since this is a fairly obscure case.  */
+      ;
+    }
+
+  /* FIXME, what about the minimal symbol table? */
+  return blewit;
+#else
+  return (0);
+#endif
+}
+\f
+/* Allocate and partially fill a partial symtab.  It will be
+   completely filled at the end of the symbol list.
+
+   FILENAME is the name of the symbol-file we are reading from. */
+
+struct partial_symtab *
+start_psymtab_common (struct objfile *objfile,
+                     struct section_offsets *section_offsets, char *filename,
+                     CORE_ADDR textlow, struct partial_symbol **global_syms,
+                     struct partial_symbol **static_syms)
+{
+  struct partial_symtab *psymtab;
+
+  psymtab = allocate_psymtab (filename, objfile);
+  psymtab->section_offsets = section_offsets;
+  psymtab->textlow = textlow;
+  psymtab->texthigh = psymtab->textlow;                /* default */
+  psymtab->globals_offset = global_syms - objfile->global_psymbols.list;
+  psymtab->statics_offset = static_syms - objfile->static_psymbols.list;
+  return (psymtab);
+}
+\f
+/* Add a symbol with a long value to a psymtab.
+   Since one arg is a struct, we pass in a ptr and deref it (sigh).  */
+
+void
+add_psymbol_to_list (char *name, int namelength, namespace_enum namespace,
+                    enum address_class class,
+                    struct psymbol_allocation_list *list, long val,    /* Value as a long */
+                    CORE_ADDR coreaddr,        /* Value as a CORE_ADDR */
+                    enum language language, struct objfile *objfile)
+{
+  register struct partial_symbol *psym;
+  char *buf = alloca (namelength + 1);
+  /* psymbol is static so that there will be no uninitialized gaps in the
+     structure which might contain random data, causing cache misses in
+     bcache. */
+  static struct partial_symbol psymbol;
+
+  /* Create local copy of the partial symbol */
+  memcpy (buf, name, namelength);
+  buf[namelength] = '\0';
+  SYMBOL_NAME (&psymbol) = bcache (buf, namelength + 1, objfile->psymbol_cache);
+  /* val and coreaddr are mutually exclusive, one of them *will* be zero */
+  if (val != 0)
+    {
+      SYMBOL_VALUE (&psymbol) = val;
+    }
+  else
+    {
+      SYMBOL_VALUE_ADDRESS (&psymbol) = coreaddr;
+    }
+  SYMBOL_SECTION (&psymbol) = 0;
+  SYMBOL_LANGUAGE (&psymbol) = language;
+  PSYMBOL_NAMESPACE (&psymbol) = namespace;
+  PSYMBOL_CLASS (&psymbol) = class;
+  SYMBOL_INIT_LANGUAGE_SPECIFIC (&psymbol, language);
+
+  /* Stash the partial symbol away in the cache */
+  psym = bcache (&psymbol, sizeof (struct partial_symbol), objfile->psymbol_cache);
+
+  /* Save pointer to partial symbol in psymtab, growing symtab if needed. */
+  if (list->next >= list->list + list->size)
+    {
+      extend_psymbol_list (list, objfile);
+    }
+  *list->next++ = psym;
+  OBJSTAT (objfile, n_psyms++);
+}
+
+/* Add a symbol with a long value to a psymtab. This differs from
+ * add_psymbol_to_list above in taking both a mangled and a demangled
+ * name. */
+
+void
+add_psymbol_with_dem_name_to_list (char *name, int namelength, char *dem_name,
+                                  int dem_namelength, namespace_enum namespace,
+                                  enum address_class class,
+                                  struct psymbol_allocation_list *list, long val,      /* Value as a long */
+                                  CORE_ADDR coreaddr,  /* Value as a CORE_ADDR */
+                                  enum language language,
+                                  struct objfile *objfile)
+{
+  register struct partial_symbol *psym;
+  char *buf = alloca (namelength + 1);
+  /* psymbol is static so that there will be no uninitialized gaps in the
+     structure which might contain random data, causing cache misses in
+     bcache. */
+  static struct partial_symbol psymbol;
+
+  /* Create local copy of the partial symbol */
+
+  memcpy (buf, name, namelength);
+  buf[namelength] = '\0';
+  SYMBOL_NAME (&psymbol) = bcache (buf, namelength + 1, objfile->psymbol_cache);
+
+  buf = alloca (dem_namelength + 1);
+  memcpy (buf, dem_name, dem_namelength);
+  buf[dem_namelength] = '\0';
+
+  switch (language)
+    {
+    case language_c:
+    case language_cplus:
+      SYMBOL_CPLUS_DEMANGLED_NAME (&psymbol) =
+       bcache (buf, dem_namelength + 1, objfile->psymbol_cache);
+      break;
+      /* OBSOLETE case language_chill: */
+      /* OBSOLETE   SYMBOL_CHILL_DEMANGLED_NAME (&psymbol) = */
+      /* OBSOLETE     bcache (buf, dem_namelength + 1, objfile->psymbol_cache); */
+
+      /* FIXME What should be done for the default case? Ignoring for now. */
+    }
+
+  /* val and coreaddr are mutually exclusive, one of them *will* be zero */
+  if (val != 0)
+    {
+      SYMBOL_VALUE (&psymbol) = val;
+    }
+  else
+    {
+      SYMBOL_VALUE_ADDRESS (&psymbol) = coreaddr;
+    }
+  SYMBOL_SECTION (&psymbol) = 0;
+  SYMBOL_LANGUAGE (&psymbol) = language;
+  PSYMBOL_NAMESPACE (&psymbol) = namespace;
+  PSYMBOL_CLASS (&psymbol) = class;
+  SYMBOL_INIT_LANGUAGE_SPECIFIC (&psymbol, language);
+
+  /* Stash the partial symbol away in the cache */
+  psym = bcache (&psymbol, sizeof (struct partial_symbol), objfile->psymbol_cache);
+
+  /* Save pointer to partial symbol in psymtab, growing symtab if needed. */
+  if (list->next >= list->list + list->size)
+    {
+      extend_psymbol_list (list, objfile);
+    }
+  *list->next++ = psym;
+  OBJSTAT (objfile, n_psyms++);
+}
+
+/* Initialize storage for partial symbols.  */
+
+void
+init_psymbol_list (struct objfile *objfile, int total_symbols)
+{
+  /* Free any previously allocated psymbol lists.  */
+
+  if (objfile->global_psymbols.list)
+    {
+      xmfree (objfile->md, (PTR) objfile->global_psymbols.list);
+    }
+  if (objfile->static_psymbols.list)
+    {
+      xmfree (objfile->md, (PTR) objfile->static_psymbols.list);
+    }
+
+  /* Current best guess is that approximately a twentieth
+     of the total symbols (in a debugging file) are global or static
+     oriented symbols */
+
+  objfile->global_psymbols.size = total_symbols / 10;
+  objfile->static_psymbols.size = total_symbols / 10;
+
+  if (objfile->global_psymbols.size > 0)
+    {
+      objfile->global_psymbols.next =
+       objfile->global_psymbols.list = (struct partial_symbol **)
+       xmmalloc (objfile->md, (objfile->global_psymbols.size
+                               * sizeof (struct partial_symbol *)));
+    }
+  if (objfile->static_psymbols.size > 0)
+    {
+      objfile->static_psymbols.next =
+       objfile->static_psymbols.list = (struct partial_symbol **)
+       xmmalloc (objfile->md, (objfile->static_psymbols.size
+                               * sizeof (struct partial_symbol *)));
+    }
+}
+
+/* OVERLAYS:
+   The following code implements an abstraction for debugging overlay sections.
+
+   The target model is as follows:
+   1) The gnu linker will permit multiple sections to be mapped into the
+   same VMA, each with its own unique LMA (or load address).
+   2) It is assumed that some runtime mechanism exists for mapping the
+   sections, one by one, from the load address into the VMA address.
+   3) This code provides a mechanism for gdb to keep track of which 
+   sections should be considered to be mapped from the VMA to the LMA.
+   This information is used for symbol lookup, and memory read/write.
+   For instance, if a section has been mapped then its contents 
+   should be read from the VMA, otherwise from the LMA.
+
+   Two levels of debugger support for overlays are available.  One is
+   "manual", in which the debugger relies on the user to tell it which
+   overlays are currently mapped.  This level of support is
+   implemented entirely in the core debugger, and the information about
+   whether a section is mapped is kept in the objfile->obj_section table.
+
+   The second level of support is "automatic", and is only available if
+   the target-specific code provides functionality to read the target's
+   overlay mapping table, and translate its contents for the debugger
+   (by updating the mapped state information in the obj_section tables).
+
+   The interface is as follows:
+   User commands:
+   overlay map <name>   -- tell gdb to consider this section mapped
+   overlay unmap <name> -- tell gdb to consider this section unmapped
+   overlay list         -- list the sections that GDB thinks are mapped
+   overlay read-target  -- get the target's state of what's mapped
+   overlay off/manual/auto -- set overlay debugging state
+   Functional interface:
+   find_pc_mapped_section(pc):    if the pc is in the range of a mapped
+   section, return that section.
+   find_pc_overlay(pc):       find any overlay section that contains 
+   the pc, either in its VMA or its LMA
+   overlay_is_mapped(sect):       true if overlay is marked as mapped
+   section_is_overlay(sect):      true if section's VMA != LMA
+   pc_in_mapped_range(pc,sec):    true if pc belongs to section's VMA
+   pc_in_unmapped_range(...):     true if pc belongs to section's LMA
+   sections_overlap(sec1, sec2):  true if mapped sec1 and sec2 ranges overlap
+   overlay_mapped_address(...):   map an address from section's LMA to VMA
+   overlay_unmapped_address(...): map an address from section's VMA to LMA
+   symbol_overlayed_address(...): Return a "current" address for symbol:
+   either in VMA or LMA depending on whether
+   the symbol's section is currently mapped
+ */
+
+/* Overlay debugging state: */
+
+enum overlay_debugging_state overlay_debugging = ovly_off;
+int overlay_cache_invalid = 0; /* True if need to refresh mapped state */
+
+/* Target vector for refreshing overlay mapped state */
+static void simple_overlay_update (struct obj_section *);
+void (*target_overlay_update) (struct obj_section *) = simple_overlay_update;
+
+/* Function: section_is_overlay (SECTION)
+   Returns true if SECTION has VMA not equal to LMA, ie. 
+   SECTION is loaded at an address different from where it will "run".  */
+
+int
+section_is_overlay (asection *section)
+{
+  /* FIXME: need bfd *, so we can use bfd_section_lma methods. */
+
+  if (overlay_debugging)
+    if (section && section->lma != 0 &&
+       section->vma != section->lma)
+      return 1;
+
+  return 0;
+}
+
+/* Function: overlay_invalidate_all (void)
+   Invalidate the mapped state of all overlay sections (mark it as stale).  */
+
+static void
+overlay_invalidate_all (void)
+{
+  struct objfile *objfile;
+  struct obj_section *sect;
+
+  ALL_OBJSECTIONS (objfile, sect)
+    if (section_is_overlay (sect->the_bfd_section))
+    sect->ovly_mapped = -1;
+}
+
+/* Function: overlay_is_mapped (SECTION)
+   Returns true if section is an overlay, and is currently mapped. 
+   Private: public access is thru function section_is_mapped.
+
+   Access to the ovly_mapped flag is restricted to this function, so
+   that we can do automatic update.  If the global flag
+   OVERLAY_CACHE_INVALID is set (by wait_for_inferior), then call
+   overlay_invalidate_all.  If the mapped state of the particular
+   section is stale, then call TARGET_OVERLAY_UPDATE to refresh it.  */
+
+static int
+overlay_is_mapped (struct obj_section *osect)
+{
+  if (osect == 0 || !section_is_overlay (osect->the_bfd_section))
+    return 0;
+
+  switch (overlay_debugging)
+    {
+    default:
+    case ovly_off:
+      return 0;                        /* overlay debugging off */
+    case ovly_auto:            /* overlay debugging automatic */
+      /* Unles there is a target_overlay_update function, 
+         there's really nothing useful to do here (can't really go auto)  */
+      if (target_overlay_update)
+       {
+         if (overlay_cache_invalid)
+           {
+             overlay_invalidate_all ();
+             overlay_cache_invalid = 0;
+           }
+         if (osect->ovly_mapped == -1)
+           (*target_overlay_update) (osect);
+       }
+      /* fall thru to manual case */
+    case ovly_on:              /* overlay debugging manual */
+      return osect->ovly_mapped == 1;
+    }
+}
+
+/* Function: section_is_mapped
+   Returns true if section is an overlay, and is currently mapped.  */
+
+int
+section_is_mapped (asection *section)
+{
+  struct objfile *objfile;
+  struct obj_section *osect;
+
+  if (overlay_debugging)
+    if (section && section_is_overlay (section))
+      ALL_OBJSECTIONS (objfile, osect)
+       if (osect->the_bfd_section == section)
+       return overlay_is_mapped (osect);
+
+  return 0;
+}
+
+/* Function: pc_in_unmapped_range
+   If PC falls into the lma range of SECTION, return true, else false.  */
+
+CORE_ADDR
+pc_in_unmapped_range (CORE_ADDR pc, asection *section)
+{
+  /* FIXME: need bfd *, so we can use bfd_section_lma methods. */
+
+  int size;
+
+  if (overlay_debugging)
+    if (section && section_is_overlay (section))
+      {
+       size = bfd_get_section_size_before_reloc (section);
+       if (section->lma <= pc && pc < section->lma + size)
+         return 1;
+      }
+  return 0;
+}
+
+/* Function: pc_in_mapped_range
+   If PC falls into the vma range of SECTION, return true, else false.  */
+
+CORE_ADDR
+pc_in_mapped_range (CORE_ADDR pc, asection *section)
+{
+  /* FIXME: need bfd *, so we can use bfd_section_vma methods. */
+
+  int size;
+
+  if (overlay_debugging)
+    if (section && section_is_overlay (section))
+      {
+       size = bfd_get_section_size_before_reloc (section);
+       if (section->vma <= pc && pc < section->vma + size)
+         return 1;
+      }
+  return 0;
+}
+
+
+/* Return true if the mapped ranges of sections A and B overlap, false
+   otherwise.  */
+int
+sections_overlap (asection *a, asection *b)
+{
+  /* FIXME: need bfd *, so we can use bfd_section_vma methods. */
+
+  CORE_ADDR a_start = a->vma;
+  CORE_ADDR a_end = a->vma + bfd_get_section_size_before_reloc (a);
+  CORE_ADDR b_start = b->vma;
+  CORE_ADDR b_end = b->vma + bfd_get_section_size_before_reloc (b);
+
+  return (a_start < b_end && b_start < a_end);
+}
+
+/* Function: overlay_unmapped_address (PC, SECTION)
+   Returns the address corresponding to PC in the unmapped (load) range.
+   May be the same as PC.  */
+
+CORE_ADDR
+overlay_unmapped_address (CORE_ADDR pc, asection *section)
+{
+  /* FIXME: need bfd *, so we can use bfd_section_lma methods. */
+
+  if (overlay_debugging)
+    if (section && section_is_overlay (section) &&
+       pc_in_mapped_range (pc, section))
+      return pc + section->lma - section->vma;
+
+  return pc;
+}
+
+/* Function: overlay_mapped_address (PC, SECTION)
+   Returns the address corresponding to PC in the mapped (runtime) range.
+   May be the same as PC.  */
+
+CORE_ADDR
+overlay_mapped_address (CORE_ADDR pc, asection *section)
+{
+  /* FIXME: need bfd *, so we can use bfd_section_vma methods. */
+
+  if (overlay_debugging)
+    if (section && section_is_overlay (section) &&
+       pc_in_unmapped_range (pc, section))
+      return pc + section->vma - section->lma;
+
+  return pc;
+}
+
+
+/* Function: symbol_overlayed_address 
+   Return one of two addresses (relative to the VMA or to the LMA),
+   depending on whether the section is mapped or not.  */
+
+CORE_ADDR
+symbol_overlayed_address (CORE_ADDR address, asection *section)
+{
+  if (overlay_debugging)
+    {
+      /* If the symbol has no section, just return its regular address. */
+      if (section == 0)
+       return address;
+      /* If the symbol's section is not an overlay, just return its address */
+      if (!section_is_overlay (section))
+       return address;
+      /* If the symbol's section is mapped, just return its address */
+      if (section_is_mapped (section))
+       return address;
+      /*
+       * HOWEVER: if the symbol is in an overlay section which is NOT mapped,
+       * then return its LOADED address rather than its vma address!!
+       */
+      return overlay_unmapped_address (address, section);
+    }
+  return address;
+}
+
+/* Function: find_pc_overlay (PC) 
+   Return the best-match overlay section for PC:
+   If PC matches a mapped overlay section's VMA, return that section.
+   Else if PC matches an unmapped section's VMA, return that section.
+   Else if PC matches an unmapped section's LMA, return that section.  */
+
+asection *
+find_pc_overlay (CORE_ADDR pc)
+{
+  struct objfile *objfile;
+  struct obj_section *osect, *best_match = NULL;
+
+  if (overlay_debugging)
+    ALL_OBJSECTIONS (objfile, osect)
+      if (section_is_overlay (osect->the_bfd_section))
+      {
+       if (pc_in_mapped_range (pc, osect->the_bfd_section))
+         {
+           if (overlay_is_mapped (osect))
+             return osect->the_bfd_section;
+           else
+             best_match = osect;
+         }
+       else if (pc_in_unmapped_range (pc, osect->the_bfd_section))
+         best_match = osect;
+      }
+  return best_match ? best_match->the_bfd_section : NULL;
+}
+
+/* Function: find_pc_mapped_section (PC)
+   If PC falls into the VMA address range of an overlay section that is 
+   currently marked as MAPPED, return that section.  Else return NULL.  */
+
+asection *
+find_pc_mapped_section (CORE_ADDR pc)
+{
+  struct objfile *objfile;
+  struct obj_section *osect;
+
+  if (overlay_debugging)
+    ALL_OBJSECTIONS (objfile, osect)
+      if (pc_in_mapped_range (pc, osect->the_bfd_section) &&
+         overlay_is_mapped (osect))
+      return osect->the_bfd_section;
+
+  return NULL;
+}
+
+/* Function: list_overlays_command
+   Print a list of mapped sections and their PC ranges */
+
+void
+list_overlays_command (char *args, int from_tty)
+{
+  int nmapped = 0;
+  struct objfile *objfile;
+  struct obj_section *osect;
+
+  if (overlay_debugging)
+    ALL_OBJSECTIONS (objfile, osect)
+      if (overlay_is_mapped (osect))
+      {
+       const char *name;
+       bfd_vma lma, vma;
+       int size;
+
+       vma = bfd_section_vma (objfile->obfd, osect->the_bfd_section);
+       lma = bfd_section_lma (objfile->obfd, osect->the_bfd_section);
+       size = bfd_get_section_size_before_reloc (osect->the_bfd_section);
+       name = bfd_section_name (objfile->obfd, osect->the_bfd_section);
+
+       printf_filtered ("Section %s, loaded at ", name);
+       print_address_numeric (lma, 1, gdb_stdout);
+       puts_filtered (" - ");
+       print_address_numeric (lma + size, 1, gdb_stdout);
+       printf_filtered (", mapped at ");
+       print_address_numeric (vma, 1, gdb_stdout);
+       puts_filtered (" - ");
+       print_address_numeric (vma + size, 1, gdb_stdout);
+       puts_filtered ("\n");
+
+       nmapped++;
+      }
+  if (nmapped == 0)
+    printf_filtered ("No sections are mapped.\n");
+}
+
+/* Function: map_overlay_command
+   Mark the named section as mapped (ie. residing at its VMA address).  */
+
+void
+map_overlay_command (char *args, int from_tty)
+{
+  struct objfile *objfile, *objfile2;
+  struct obj_section *sec, *sec2;
+  asection *bfdsec;
+
+  if (!overlay_debugging)
+    error ("\
+Overlay debugging not enabled.  Use either the 'overlay auto' or\n\
+the 'overlay manual' command.");
+
+  if (args == 0 || *args == 0)
+    error ("Argument required: name of an overlay section");
+
+  /* First, find a section matching the user supplied argument */
+  ALL_OBJSECTIONS (objfile, sec)
+    if (!strcmp (bfd_section_name (objfile->obfd, sec->the_bfd_section), args))
+    {
+      /* Now, check to see if the section is an overlay. */
+      bfdsec = sec->the_bfd_section;
+      if (!section_is_overlay (bfdsec))
+       continue;               /* not an overlay section */
+
+      /* Mark the overlay as "mapped" */
+      sec->ovly_mapped = 1;
+
+      /* Next, make a pass and unmap any sections that are
+         overlapped by this new section: */
+      ALL_OBJSECTIONS (objfile2, sec2)
+       if (sec2->ovly_mapped
+            && sec != sec2
+            && sec->the_bfd_section != sec2->the_bfd_section
+            && sections_overlap (sec->the_bfd_section,
+                                 sec2->the_bfd_section))
+       {
+         if (info_verbose)
+           printf_filtered ("Note: section %s unmapped by overlap\n",
+                            bfd_section_name (objfile->obfd,
+                                              sec2->the_bfd_section));
+         sec2->ovly_mapped = 0;        /* sec2 overlaps sec: unmap sec2 */
+       }
+      return;
+    }
+  error ("No overlay section called %s", args);
+}
+
+/* Function: unmap_overlay_command
+   Mark the overlay section as unmapped 
+   (ie. resident in its LMA address range, rather than the VMA range).  */
+
+void
+unmap_overlay_command (char *args, int from_tty)
+{
+  struct objfile *objfile;
+  struct obj_section *sec;
+
+  if (!overlay_debugging)
+    error ("\
+Overlay debugging not enabled.  Use either the 'overlay auto' or\n\
+the 'overlay manual' command.");
+
+  if (args == 0 || *args == 0)
+    error ("Argument required: name of an overlay section");
+
+  /* First, find a section matching the user supplied argument */
+  ALL_OBJSECTIONS (objfile, sec)
+    if (!strcmp (bfd_section_name (objfile->obfd, sec->the_bfd_section), args))
+    {
+      if (!sec->ovly_mapped)
+       error ("Section %s is not mapped", args);
+      sec->ovly_mapped = 0;
+      return;
+    }
+  error ("No overlay section called %s", args);
+}
+
+/* Function: overlay_auto_command
+   A utility command to turn on overlay debugging.
+   Possibly this should be done via a set/show command. */
+
+static void
+overlay_auto_command (char *args, int from_tty)
+{
+  overlay_debugging = ovly_auto;
+  enable_overlay_breakpoints ();
+  if (info_verbose)
+    printf_filtered ("Automatic overlay debugging enabled.");
+}
+
+/* Function: overlay_manual_command
+   A utility command to turn on overlay debugging.
+   Possibly this should be done via a set/show command. */
+
+static void
+overlay_manual_command (char *args, int from_tty)
+{
+  overlay_debugging = ovly_on;
+  disable_overlay_breakpoints ();
+  if (info_verbose)
+    printf_filtered ("Overlay debugging enabled.");
+}
+
+/* Function: overlay_off_command
+   A utility command to turn on overlay debugging.
+   Possibly this should be done via a set/show command. */
+
+static void
+overlay_off_command (char *args, int from_tty)
+{
+  overlay_debugging = ovly_off;
+  disable_overlay_breakpoints ();
+  if (info_verbose)
+    printf_filtered ("Overlay debugging disabled.");
+}
+
+static void
+overlay_load_command (char *args, int from_tty)
+{
+  if (target_overlay_update)
+    (*target_overlay_update) (NULL);
+  else
+    error ("This target does not know how to read its overlay state.");
+}
+
+/* Function: overlay_command
+   A place-holder for a mis-typed command */
+
+/* Command list chain containing all defined "overlay" subcommands. */
+struct cmd_list_element *overlaylist;
+
+static void
+overlay_command (char *args, int from_tty)
+{
+  printf_unfiltered
+    ("\"overlay\" must be followed by the name of an overlay command.\n");
+  help_list (overlaylist, "overlay ", -1, gdb_stdout);
+}
+
+
+/* Target Overlays for the "Simplest" overlay manager:
+
+   This is GDB's default target overlay layer.  It works with the 
+   minimal overlay manager supplied as an example by Cygnus.  The 
+   entry point is via a function pointer "target_overlay_update", 
+   so targets that use a different runtime overlay manager can 
+   substitute their own overlay_update function and take over the
+   function pointer.
+
+   The overlay_update function pokes around in the target's data structures
+   to see what overlays are mapped, and updates GDB's overlay mapping with
+   this information.
+
+   In this simple implementation, the target data structures are as follows:
+   unsigned _novlys;            /# number of overlay sections #/
+   unsigned _ovly_table[_novlys][4] = {
+   {VMA, SIZE, LMA, MAPPED},    /# one entry per overlay section #/
+   {..., ...,  ..., ...},
+   }
+   unsigned _novly_regions;     /# number of overlay regions #/
+   unsigned _ovly_region_table[_novly_regions][3] = {
+   {VMA, SIZE, MAPPED_TO_LMA},  /# one entry per overlay region #/
+   {..., ...,  ...},
+   }
+   These functions will attempt to update GDB's mappedness state in the
+   symbol section table, based on the target's mappedness state.
+
+   To do this, we keep a cached copy of the target's _ovly_table, and
+   attempt to detect when the cached copy is invalidated.  The main
+   entry point is "simple_overlay_update(SECT), which looks up SECT in
+   the cached table and re-reads only the entry for that section from
+   the target (whenever possible).
+ */
+
+/* Cached, dynamically allocated copies of the target data structures: */
+static unsigned (*cache_ovly_table)[4] = 0;
+#if 0
+static unsigned (*cache_ovly_region_table)[3] = 0;
+#endif
+static unsigned cache_novlys = 0;
+#if 0
+static unsigned cache_novly_regions = 0;
+#endif
+static CORE_ADDR cache_ovly_table_base = 0;
+#if 0
+static CORE_ADDR cache_ovly_region_table_base = 0;
+#endif
+enum ovly_index
+  {
+    VMA, SIZE, LMA, MAPPED
+  };
+#define TARGET_LONG_BYTES (TARGET_LONG_BIT / TARGET_CHAR_BIT)
+
+/* Throw away the cached copy of _ovly_table */
+static void
+simple_free_overlay_table (void)
+{
+  if (cache_ovly_table)
+    xfree (cache_ovly_table);
+  cache_novlys = 0;
+  cache_ovly_table = NULL;
+  cache_ovly_table_base = 0;
+}
+
+#if 0
+/* Throw away the cached copy of _ovly_region_table */
+static void
+simple_free_overlay_region_table (void)
+{
+  if (cache_ovly_region_table)
+    xfree (cache_ovly_region_table);
+  cache_novly_regions = 0;
+  cache_ovly_region_table = NULL;
+  cache_ovly_region_table_base = 0;
+}
+#endif
+
+/* Read an array of ints from the target into a local buffer.
+   Convert to host order.  int LEN is number of ints  */
+static void
+read_target_long_array (CORE_ADDR memaddr, unsigned int *myaddr, int len)
+{
+  /* FIXME (alloca): Not safe if array is very large. */
+  char *buf = alloca (len * TARGET_LONG_BYTES);
+  int i;
+
+  read_memory (memaddr, buf, len * TARGET_LONG_BYTES);
+  for (i = 0; i < len; i++)
+    myaddr[i] = extract_unsigned_integer (TARGET_LONG_BYTES * i + buf,
+                                         TARGET_LONG_BYTES);
+}
+
+/* Find and grab a copy of the target _ovly_table
+   (and _novlys, which is needed for the table's size) */
+static int
+simple_read_overlay_table (void)
+{
+  struct minimal_symbol *novlys_msym, *ovly_table_msym;
+
+  simple_free_overlay_table ();
+  novlys_msym = lookup_minimal_symbol ("_novlys", NULL, NULL);
+  if (! novlys_msym)
+    {
+      error ("Error reading inferior's overlay table: "
+             "couldn't find `_novlys' variable\n"
+             "in inferior.  Use `overlay manual' mode.");
+      return 0;
+    }
+
+  ovly_table_msym = lookup_minimal_symbol ("_ovly_table", NULL, NULL);
+  if (! ovly_table_msym)
+    {
+      error ("Error reading inferior's overlay table: couldn't find "
+             "`_ovly_table' array\n"
+             "in inferior.  Use `overlay manual' mode.");
+      return 0;
+    }
+
+  cache_novlys = read_memory_integer (SYMBOL_VALUE_ADDRESS (novlys_msym), 4);
+  cache_ovly_table
+    = (void *) xmalloc (cache_novlys * sizeof (*cache_ovly_table));
+  cache_ovly_table_base = SYMBOL_VALUE_ADDRESS (ovly_table_msym);
+  read_target_long_array (cache_ovly_table_base,
+                          (int *) cache_ovly_table,
+                          cache_novlys * 4);
+
+  return 1;                    /* SUCCESS */
+}
+
+#if 0
+/* Find and grab a copy of the target _ovly_region_table
+   (and _novly_regions, which is needed for the table's size) */
+static int
+simple_read_overlay_region_table (void)
+{
+  struct minimal_symbol *msym;
+
+  simple_free_overlay_region_table ();
+  msym = lookup_minimal_symbol ("_novly_regions", NULL, NULL);
+  if (msym != NULL)
+    cache_novly_regions = read_memory_integer (SYMBOL_VALUE_ADDRESS (msym), 4);
+  else
+    return 0;                  /* failure */
+  cache_ovly_region_table = (void *) xmalloc (cache_novly_regions * 12);
+  if (cache_ovly_region_table != NULL)
+    {
+      msym = lookup_minimal_symbol ("_ovly_region_table", NULL, NULL);
+      if (msym != NULL)
+       {
+         cache_ovly_region_table_base = SYMBOL_VALUE_ADDRESS (msym);
+         read_target_long_array (cache_ovly_region_table_base,
+                                 (int *) cache_ovly_region_table,
+                                 cache_novly_regions * 3);
+       }
+      else
+       return 0;               /* failure */
+    }
+  else
+    return 0;                  /* failure */
+  return 1;                    /* SUCCESS */
+}
+#endif
+
+/* Function: simple_overlay_update_1 
+   A helper function for simple_overlay_update.  Assuming a cached copy
+   of _ovly_table exists, look through it to find an entry whose vma,
+   lma and size match those of OSECT.  Re-read the entry and make sure
+   it still matches OSECT (else the table may no longer be valid).
+   Set OSECT's mapped state to match the entry.  Return: 1 for
+   success, 0 for failure.  */
+
+static int
+simple_overlay_update_1 (struct obj_section *osect)
+{
+  int i, size;
+  bfd *obfd = osect->objfile->obfd;
+  asection *bsect = osect->the_bfd_section;
+
+  size = bfd_get_section_size_before_reloc (osect->the_bfd_section);
+  for (i = 0; i < cache_novlys; i++)
+    if (cache_ovly_table[i][VMA] == bfd_section_vma (obfd, bsect)
+       && cache_ovly_table[i][LMA] == bfd_section_lma (obfd, bsect)
+       /* && cache_ovly_table[i][SIZE] == size */ )
+      {
+       read_target_long_array (cache_ovly_table_base + i * TARGET_LONG_BYTES,
+                               (int *) cache_ovly_table[i], 4);
+       if (cache_ovly_table[i][VMA] == bfd_section_vma (obfd, bsect)
+           && cache_ovly_table[i][LMA] == bfd_section_lma (obfd, bsect)
+           /* && cache_ovly_table[i][SIZE] == size */ )
+         {
+           osect->ovly_mapped = cache_ovly_table[i][MAPPED];
+           return 1;
+         }
+       else    /* Warning!  Warning!  Target's ovly table has changed! */
+         return 0;
+      }
+  return 0;
+}
+
+/* Function: simple_overlay_update
+   If OSECT is NULL, then update all sections' mapped state 
+   (after re-reading the entire target _ovly_table). 
+   If OSECT is non-NULL, then try to find a matching entry in the 
+   cached ovly_table and update only OSECT's mapped state.
+   If a cached entry can't be found or the cache isn't valid, then 
+   re-read the entire cache, and go ahead and update all sections.  */
+
+static void
+simple_overlay_update (struct obj_section *osect)
+{
+  struct objfile *objfile;
+
+  /* Were we given an osect to look up?  NULL means do all of them. */
+  if (osect)
+    /* Have we got a cached copy of the target's overlay table? */
+    if (cache_ovly_table != NULL)
+      /* Does its cached location match what's currently in the symtab? */
+      if (cache_ovly_table_base ==
+         SYMBOL_VALUE_ADDRESS (lookup_minimal_symbol ("_ovly_table", NULL, NULL)))
+       /* Then go ahead and try to look up this single section in the cache */
+       if (simple_overlay_update_1 (osect))
+         /* Found it!  We're done. */
+         return;
+
+  /* Cached table no good: need to read the entire table anew.
+     Or else we want all the sections, in which case it's actually
+     more efficient to read the whole table in one block anyway.  */
+
+  if (! simple_read_overlay_table ())
+    return;
+
+  /* Now may as well update all sections, even if only one was requested. */
+  ALL_OBJSECTIONS (objfile, osect)
+    if (section_is_overlay (osect->the_bfd_section))
+    {
+      int i, size;
+      bfd *obfd = osect->objfile->obfd;
+      asection *bsect = osect->the_bfd_section;
+
+      size = bfd_get_section_size_before_reloc (osect->the_bfd_section);
+      for (i = 0; i < cache_novlys; i++)
+       if (cache_ovly_table[i][VMA] == bfd_section_vma (obfd, bsect)
+           && cache_ovly_table[i][LMA] == bfd_section_lma (obfd, bsect)
+           /* && cache_ovly_table[i][SIZE] == size */ )
+         { /* obj_section matches i'th entry in ovly_table */
+           osect->ovly_mapped = cache_ovly_table[i][MAPPED];
+           break;              /* finished with inner for loop: break out */
+         }
+    }
+}
+
+
+void
+_initialize_symfile (void)
+{
+  struct cmd_list_element *c;
+
+  c = add_cmd ("symbol-file", class_files, symbol_file_command,
+              "Load symbol table from executable file FILE.\n\
+The `file' command can also load symbol tables, as well as setting the file\n\
+to execute.", &cmdlist);
+  set_cmd_completer (c, filename_completer);
+
+  c = add_cmd ("add-symbol-file", class_files, add_symbol_file_command,
+              "Usage: add-symbol-file FILE ADDR [-s <SECT> <SECT_ADDR> -s <SECT> <SECT_ADDR> ...]\n\
+Load the symbols from FILE, assuming FILE has been dynamically loaded.\n\
+ADDR is the starting address of the file's text.\n\
+The optional arguments are section-name section-address pairs and\n\
+should be specified if the data and bss segments are not contiguous\n\
+with the text.  SECT is a section name to be loaded at SECT_ADDR.",
+              &cmdlist);
+  set_cmd_completer (c, filename_completer);
+
+  c = add_cmd ("add-shared-symbol-files", class_files,
+              add_shared_symbol_files_command,
+   "Load the symbols from shared objects in the dynamic linker's link map.",
+              &cmdlist);
+  c = add_alias_cmd ("assf", "add-shared-symbol-files", class_files, 1,
+                    &cmdlist);
+
+  c = add_cmd ("load", class_files, load_command,
+              "Dynamically load FILE into the running program, and record its symbols\n\
+for access from GDB.", &cmdlist);
+  set_cmd_completer (c, filename_completer);
+
+  add_show_from_set
+    (add_set_cmd ("symbol-reloading", class_support, var_boolean,
+                 (char *) &symbol_reloading,
+           "Set dynamic symbol table reloading multiple times in one run.",
+                 &setlist),
+     &showlist);
+
+  add_prefix_cmd ("overlay", class_support, overlay_command,
+                 "Commands for debugging overlays.", &overlaylist,
+                 "overlay ", 0, &cmdlist);
+
+  add_com_alias ("ovly", "overlay", class_alias, 1);
+  add_com_alias ("ov", "overlay", class_alias, 1);
+
+  add_cmd ("map-overlay", class_support, map_overlay_command,
+          "Assert that an overlay section is mapped.", &overlaylist);
+
+  add_cmd ("unmap-overlay", class_support, unmap_overlay_command,
+          "Assert that an overlay section is unmapped.", &overlaylist);
+
+  add_cmd ("list-overlays", class_support, list_overlays_command,
+          "List mappings of overlay sections.", &overlaylist);
+
+  add_cmd ("manual", class_support, overlay_manual_command,
+          "Enable overlay debugging.", &overlaylist);
+  add_cmd ("off", class_support, overlay_off_command,
+          "Disable overlay debugging.", &overlaylist);
+  add_cmd ("auto", class_support, overlay_auto_command,
+          "Enable automatic overlay debugging.", &overlaylist);
+  add_cmd ("load-target", class_support, overlay_load_command,
+          "Read the overlay mapping state from the target.", &overlaylist);
+
+  /* Filename extension to source language lookup table: */
+  init_filename_language_table ();
+  c = add_set_cmd ("extension-language", class_files, var_string_noescape,
+                  (char *) &ext_args,
+                  "Set mapping between filename extension and source language.\n\
+Usage: set extension-language .foo bar",
+                  &setlist);
+  set_cmd_cfunc (c, set_ext_lang_command);
+
+  add_info ("extensions", info_ext_lang_command,
+           "All filename extensions associated with a source language.");
+
+  add_show_from_set
+    (add_set_cmd ("download-write-size", class_obscure,
+                 var_integer, (char *) &download_write_size,
+                 "Set the write size used when downloading a program.\n"
+                 "Only used when downloading a program onto a remote\n"
+                 "target. Specify zero, or a negative value, to disable\n"
+                 "blocked writes. The actual size of each transfer is also\n"
+                 "limited by the size of the target packet and the memory\n"
+                 "cache.\n",
+                 &setlist),
+     &showlist);
+}
diff --git a/gdb/symfile.h b/gdb/symfile.h
new file mode 100644 (file)
index 0000000..39eb308
--- /dev/null
@@ -0,0 +1,328 @@
+/* Definitions for reading symbol files into GDB.
+   Copyright 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
+   2000, 2001
+   Free Software Foundation, Inc.
+
+   This file is part of GDB.
+
+   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.  */
+
+#if !defined (SYMFILE_H)
+#define SYMFILE_H
+
+/* This file requires that you first include "bfd.h".  */
+
+/* Partial symbols are stored in the psymbol_cache and pointers to them
+   are kept in a dynamically grown array that is obtained from malloc and
+   grown as necessary via realloc.  Each objfile typically has two of these,
+   one for global symbols and one for static symbols.  Although this adds
+   a level of indirection for storing or accessing the partial symbols,
+   it allows us to throw away duplicate psymbols and set all pointers
+   to the single saved instance. */
+
+struct psymbol_allocation_list
+  {
+
+    /* Pointer to beginning of dynamically allocated array of pointers to
+       partial symbols.  The array is dynamically expanded as necessary to
+       accommodate more pointers. */
+
+    struct partial_symbol **list;
+
+    /* Pointer to next available slot in which to store a pointer to a partial
+       symbol. */
+
+    struct partial_symbol **next;
+
+    /* Number of allocated pointer slots in current dynamic array (not the
+       number of bytes of storage).  The "next" pointer will always point
+       somewhere between list[0] and list[size], and when at list[size] the
+       array will be expanded on the next attempt to store a pointer. */
+
+    int size;
+  };
+
+/* Define an array of addresses to accommodate non-contiguous dynamic
+   loading of modules.  This is for use when entering commands, so we
+   can keep track of the section names until we read the file and
+   can map them to bfd sections.  This structure is also used by
+   solib.c to communicate the section addresses in shared objects to
+   symbol_file_add (). */
+#define MAX_SECTIONS 64
+struct section_addr_info 
+{
+  /* Sections whose names are file format dependent. */
+  struct other_sections
+  {
+    CORE_ADDR addr;
+    char *name;
+    int sectindex;
+  } other[MAX_SECTIONS];
+};
+
+/* Structure to keep track of symbol reading functions for various
+   object file types.  */
+
+struct sym_fns
+  {
+
+    /* BFD flavour that we handle, or (as a special kludge, see xcoffread.c,
+       (enum bfd_flavour)-1 for xcoff).  */
+
+    enum bfd_flavour sym_flavour;
+
+    /* Initializes anything that is global to the entire symbol table.  It is
+       called during symbol_file_add, when we begin debugging an entirely new
+       program. */
+
+    void (*sym_new_init) (struct objfile *);
+
+    /* Reads any initial information from a symbol file, and initializes the
+       struct sym_fns SF in preparation for sym_read().  It is called every
+       time we read a symbol file for any reason. */
+
+    void (*sym_init) (struct objfile *);
+
+    /* sym_read (objfile, mainline)
+       Reads a symbol file into a psymtab (or possibly a symtab).
+       OBJFILE is the objfile struct for the file we are reading.
+       MAINLINE is 1 if this is the
+       main symbol table being read, and 0 if a secondary
+       symbol file (e.g. shared library or dynamically loaded file)
+       is being read.  */
+
+    void (*sym_read) (struct objfile *, int);
+
+    /* Called when we are finished with an objfile.  Should do all cleanup
+       that is specific to the object file format for the particular objfile. */
+
+    void (*sym_finish) (struct objfile *);
+
+    /* This function produces a file-dependent section_offsets structure,
+       allocated in the objfile's storage, and based on the parameter.
+       The parameter is currently a CORE_ADDR (FIXME!) for backward compatibility
+       with the higher levels of GDB.  It should probably be changed to
+       a string, where NULL means the default, and others are parsed in a file
+       dependent way. */
+
+    void (*sym_offsets) (struct objfile *, struct section_addr_info *);
+
+    /* Finds the next struct sym_fns.  They are allocated and initialized
+       in whatever module implements the functions pointed to; an 
+       initializer calls add_symtab_fns to add them to the global chain.  */
+
+    struct sym_fns *next;
+
+  };
+
+/* The default version of sym_fns.sym_offsets for readers that don't
+   do anything special.  */
+
+extern void
+default_symfile_offsets (struct objfile *objfile, struct section_addr_info *);
+
+
+extern void
+extend_psymbol_list (struct psymbol_allocation_list *, struct objfile *);
+
+/* Add any kind of symbol to a psymbol_allocation_list. */
+
+/* #include "demangle.h" */
+
+extern void
+add_psymbol_to_list (char *, int, namespace_enum, enum address_class,
+                    struct psymbol_allocation_list *, long, CORE_ADDR,
+                    enum language, struct objfile *);
+
+extern void
+add_psymbol_with_dem_name_to_list (char *, int, char *, int, namespace_enum,
+                                  enum address_class,
+                                  struct psymbol_allocation_list *,
+                                  long, CORE_ADDR,
+                                  enum language, struct objfile *);
+
+
+extern void init_psymbol_list (struct objfile *, int);
+
+extern void sort_pst_symbols (struct partial_symtab *);
+
+extern struct symtab *allocate_symtab (char *, struct objfile *);
+
+extern int free_named_symtabs (char *);
+
+extern void fill_in_vptr_fieldno (struct type *);
+
+extern void add_symtab_fns (struct sym_fns *);
+
+extern void init_entry_point_info (struct objfile *);
+
+extern void
+syms_from_objfile (struct objfile *, struct section_addr_info *, int, int);
+
+extern void new_symfile_objfile (struct objfile *, int, int);
+
+extern struct objfile *symbol_file_add (char *, int,
+                                       struct section_addr_info *, int, int);
+
+/* Build (allocate and populate) a section_addr_info struct from
+   an existing section table. */
+
+struct section_table;
+extern struct section_addr_info *
+build_section_addr_info_from_section_table (const struct section_table *start,
+                                            const struct section_table *end);
+
+/* Free all memory allocated by build_section_addr_info_from_section_table. */
+
+extern void
+free_section_addr_info (struct section_addr_info *);
+
+
+extern struct partial_symtab *start_psymtab_common (struct objfile *,
+                                                   struct section_offsets *,
+                                                   char *, CORE_ADDR,
+                                                   struct partial_symbol **,
+                                                   struct partial_symbol **);
+
+/* Sorting your symbols for fast lookup or alphabetical printing.  */
+
+extern void sort_block_syms (struct block *);
+
+extern void sort_symtab_syms (struct symtab *);
+
+/* Make a copy of the string at PTR with SIZE characters in the symbol obstack
+   (and add a null character at the end in the copy).
+   Returns the address of the copy.  */
+
+extern char *obsavestring (char *, int, struct obstack *);
+
+/* Concatenate strings S1, S2 and S3; return the new string.
+   Space is found in the symbol_obstack.  */
+
+extern char *obconcat (struct obstack *obstackp, const char *, const char *,
+                      const char *);
+
+                       /*   Variables   */
+
+/* If non-zero, shared library symbols will be added automatically
+   when the inferior is created, new libraries are loaded, or when
+   attaching to the inferior.  This is almost always what users will
+   want to have happen; but for very large programs, the startup time
+   will be excessive, and so if this is a problem, the user can clear
+   this flag and then add the shared library symbols as needed.  Note
+   that there is a potential for confusion, since if the shared
+   library symbols are not loaded, commands like "info fun" will *not*
+   report all the functions that are actually present. */
+
+extern int auto_solib_add;
+
+/* For systems that support it, a threshold size in megabytes.  If
+   automatically adding a new library's symbol table to those already
+   known to the debugger would cause the total shared library symbol
+   size to exceed this threshhold, then the shlib's symbols are not
+   added.  The threshold is ignored if the user explicitly asks for a
+   shlib to be added, such as when using the "sharedlibrary"
+   command. */
+
+extern int auto_solib_limit;
+
+/* From symfile.c */
+
+extern CORE_ADDR entry_point_address (void);
+
+extern struct partial_symtab *allocate_psymtab (char *, struct objfile *);
+
+extern void discard_psymtab (struct partial_symtab *);
+
+extern void find_lowest_section (bfd *, asection *, PTR);
+
+extern bfd *symfile_bfd_open (char *);
+
+extern int get_section_index (struct objfile *, char *);
+
+/* Utility functions for overlay sections: */
+extern enum overlay_debugging_state {
+  ovly_off, 
+  ovly_on, 
+  ovly_auto
+} overlay_debugging;
+extern int overlay_cache_invalid;
+
+/* return the "mapped" overlay section  containing the PC */
+extern asection *find_pc_mapped_section (CORE_ADDR);
+
+/* return any overlay section containing the PC (even in its LMA region) */
+extern asection *find_pc_overlay (CORE_ADDR);
+
+/* return true if the section is an overlay */
+extern int section_is_overlay (asection *);
+
+/* return true if the overlay section is currently "mapped" */
+extern int section_is_mapped (asection *);
+
+/* return true if pc belongs to section's VMA */
+extern CORE_ADDR pc_in_mapped_range (CORE_ADDR, asection *);
+
+/* return true if pc belongs to section's LMA */
+extern CORE_ADDR pc_in_unmapped_range (CORE_ADDR, asection *);
+
+/* map an address from a section's LMA to its VMA */
+extern CORE_ADDR overlay_mapped_address (CORE_ADDR, asection *);
+
+/* map an address from a section's VMA to its LMA */
+extern CORE_ADDR overlay_unmapped_address (CORE_ADDR, asection *);
+
+/* convert an address in an overlay section (force into VMA range) */
+extern CORE_ADDR symbol_overlayed_address (CORE_ADDR, asection *);
+
+/* Load symbols from a file. */
+extern void symbol_file_add_main (char *args, int from_tty);
+
+/* Clear GDB symbol tables. */
+extern void symbol_file_clear (int from_tty);
+
+/* From dwarfread.c */
+
+extern void
+dwarf_build_psymtabs (struct objfile *, int, file_ptr, unsigned int,
+                     file_ptr, unsigned int);
+
+/* From dwarf2read.c */
+
+extern int dwarf2_has_info (bfd * abfd);
+
+extern void dwarf2_build_psymtabs (struct objfile *, int);
+extern void dwarf2_build_frame_info (struct objfile *);
+
+/* From mdebugread.c */
+
+/* Hack to force structures to exist before use in parameter list.  */
+struct ecoff_debug_hack
+  {
+    struct ecoff_debug_swap *a;
+    struct ecoff_debug_info *b;
+  };
+extern void
+mdebug_build_psymtabs (struct objfile *,
+                      const struct ecoff_debug_swap *,
+                      struct ecoff_debug_info *);
+
+extern void
+elfmdebug_build_psymtabs (struct objfile *,
+                         const struct ecoff_debug_swap *, asection *);
+
+#endif /* !defined(SYMFILE_H) */
diff --git a/gdb/symtab.c b/gdb/symtab.c
new file mode 100644 (file)
index 0000000..a432292
--- /dev/null
@@ -0,0 +1,4063 @@
+/* Symbol table lookup for the GNU debugger, GDB.
+
+   Copyright 1986, 1987, 1988, 1989, 1990, 1991, 1992, 1993, 1994,
+   1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002 Free Software
+   Foundation, Inc.
+
+   This file is part of GDB.
+
+   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.  */
+
+#include "defs.h"
+#include "symtab.h"
+#include "gdbtypes.h"
+#include "gdbcore.h"
+#include "frame.h"
+#include "target.h"
+#include "value.h"
+#include "symfile.h"
+#include "objfiles.h"
+#include "gdbcmd.h"
+#include "call-cmds.h"
+#include "gdb_regex.h"
+#include "expression.h"
+#include "language.h"
+#include "demangle.h"
+#include "inferior.h"
+#include "linespec.h"
+#include "source.h"
+#include "filenames.h"         /* for FILENAME_CMP */
+
+#include "gdb_obstack.h"
+
+#include <sys/types.h>
+#include <fcntl.h>
+#include "gdb_string.h"
+#include "gdb_stat.h"
+#include <ctype.h>
+#include "cp-abi.h"
+
+/* Prototype for one function in parser-defs.h,
+   instead of including that entire file. */
+
+extern char *find_template_name_end (char *);
+
+/* Prototypes for local functions */
+
+static void completion_list_add_name (char *, char *, int, char *, char *);
+
+static void rbreak_command (char *, int);
+
+static void types_info (char *, int);
+
+static void functions_info (char *, int);
+
+static void variables_info (char *, int);
+
+static void sources_info (char *, int);
+
+static void output_source_filename (char *, int *);
+
+static int find_line_common (struct linetable *, int, int *);
+
+/* This one is used by linespec.c */
+
+char *operator_chars (char *p, char **end);
+
+static struct partial_symbol *lookup_partial_symbol (struct partial_symtab *,
+                                                    const char *, int,
+                                                    namespace_enum);
+
+static struct symbol *lookup_symbol_aux (const char *name,
+                                        const char *mangled_name,
+                                        const struct block *block,
+                                        const namespace_enum namespace,
+                                        int *is_a_field_of_this,
+                                        struct symtab **symtab);
+
+
+static struct symbol *find_active_alias (struct symbol *sym, CORE_ADDR addr);
+
+/* This flag is used in hppa-tdep.c, and set in hp-symtab-read.c */
+/* Signals the presence of objects compiled by HP compilers */
+int hp_som_som_object_present = 0;
+
+static void fixup_section (struct general_symbol_info *, struct objfile *);
+
+static int file_matches (char *, char **, int);
+
+static void print_symbol_info (namespace_enum,
+                              struct symtab *, struct symbol *, int, char *);
+
+static void print_msymbol_info (struct minimal_symbol *);
+
+static void symtab_symbol_info (char *, namespace_enum, int);
+
+static void overload_list_add_symbol (struct symbol *sym, char *oload_name);
+
+void _initialize_symtab (void);
+
+/* */
+
+/* The single non-language-specific builtin type */
+struct type *builtin_type_error;
+
+/* Block in which the most recently searched-for symbol was found.
+   Might be better to make this a parameter to lookup_symbol and 
+   value_of_this. */
+
+const struct block *block_found;
+
+/* While the C++ support is still in flux, issue a possibly helpful hint on
+   using the new command completion feature on single quoted demangled C++
+   symbols.  Remove when loose ends are cleaned up.   FIXME -fnf */
+
+static void
+cplusplus_hint (char *name)
+{
+  while (*name == '\'')
+    name++;
+  printf_filtered ("Hint: try '%s<TAB> or '%s<ESC-?>\n", name, name);
+  printf_filtered ("(Note leading single quote.)\n");
+}
+
+/* Check for a symtab of a specific name; first in symtabs, then in
+   psymtabs.  *If* there is no '/' in the name, a match after a '/'
+   in the symtab filename will also work.  */
+
+struct symtab *
+lookup_symtab (const char *name)
+{
+  register struct symtab *s;
+  register struct partial_symtab *ps;
+  register struct objfile *objfile;
+  char *real_path = NULL;
+  char *full_path = NULL;
+
+  /* Here we are interested in canonicalizing an absolute path, not
+     absolutizing a relative path.  */
+  if (IS_ABSOLUTE_PATH (name))
+    {
+      full_path = xfullpath (name);
+      make_cleanup (xfree, full_path);
+      real_path = gdb_realpath (name);
+      make_cleanup (xfree, real_path);
+    }
+
+got_symtab:
+
+  /* First, search for an exact match */
+
+  ALL_SYMTABS (objfile, s)
+  {
+    if (FILENAME_CMP (name, s->filename) == 0)
+      {
+       return s;
+      }
+      
+    /* If the user gave us an absolute path, try to find the file in
+       this symtab and use its absolute path.  */
+    
+    if (full_path != NULL)
+      {
+       const char *fp = symtab_to_filename (s);
+       if (FILENAME_CMP (full_path, fp) == 0)
+         {
+           return s;
+         }
+      }
+
+    if (real_path != NULL)
+      {
+       char *rp = gdb_realpath (symtab_to_filename (s));
+        make_cleanup (xfree, rp);
+       if (FILENAME_CMP (real_path, rp) == 0)
+         {
+           return s;
+         }
+      }
+  }
+
+  /* Now, search for a matching tail (only if name doesn't have any dirs) */
+
+  if (lbasename (name) == name)
+    ALL_SYMTABS (objfile, s)
+    {
+      if (FILENAME_CMP (lbasename (s->filename), name) == 0)
+       return s;
+    }
+
+  /* Same search rules as above apply here, but now we look thru the
+     psymtabs.  */
+
+  ps = lookup_partial_symtab (name);
+  if (!ps)
+    return (NULL);
+
+  if (ps->readin)
+    error ("Internal: readin %s pst for `%s' found when no symtab found.",
+          ps->filename, name);
+
+  s = PSYMTAB_TO_SYMTAB (ps);
+
+  if (s)
+    return s;
+
+  /* At this point, we have located the psymtab for this file, but
+     the conversion to a symtab has failed.  This usually happens
+     when we are looking up an include file.  In this case,
+     PSYMTAB_TO_SYMTAB doesn't return a symtab, even though one has
+     been created.  So, we need to run through the symtabs again in
+     order to find the file.
+     XXX - This is a crock, and should be fixed inside of the the
+     symbol parsing routines. */
+  goto got_symtab;
+}
+
+/* Lookup the partial symbol table of a source file named NAME.
+   *If* there is no '/' in the name, a match after a '/'
+   in the psymtab filename will also work.  */
+
+struct partial_symtab *
+lookup_partial_symtab (const char *name)
+{
+  register struct partial_symtab *pst;
+  register struct objfile *objfile;
+  char *full_path = NULL;
+  char *real_path = NULL;
+
+  /* Here we are interested in canonicalizing an absolute path, not
+     absolutizing a relative path.  */
+  if (IS_ABSOLUTE_PATH (name))
+    {
+      full_path = xfullpath (name);
+      make_cleanup (xfree, full_path);
+      real_path = gdb_realpath (name);
+      make_cleanup (xfree, real_path);
+    }
+
+  ALL_PSYMTABS (objfile, pst)
+  {
+    if (FILENAME_CMP (name, pst->filename) == 0)
+      {
+       return (pst);
+      }
+
+    /* If the user gave us an absolute path, try to find the file in
+       this symtab and use its absolute path.  */
+    if (full_path != NULL)
+      {
+       if (pst->fullname == NULL)
+         source_full_path_of (pst->filename, &pst->fullname);
+       if (pst->fullname != NULL
+           && FILENAME_CMP (full_path, pst->fullname) == 0)
+         {
+           return pst;
+         }
+      }
+
+    if (real_path != NULL)
+      {
+        char *rp = NULL;
+       if (pst->fullname == NULL)
+         source_full_path_of (pst->filename, &pst->fullname);
+        if (pst->fullname != NULL)
+          {
+            rp = gdb_realpath (pst->fullname);
+            make_cleanup (xfree, rp);
+          }
+       if (rp != NULL && FILENAME_CMP (real_path, rp) == 0)
+         {
+           return pst;
+         }
+      }
+  }
+
+  /* Now, search for a matching tail (only if name doesn't have any dirs) */
+
+  if (lbasename (name) == name)
+    ALL_PSYMTABS (objfile, pst)
+    {
+      if (FILENAME_CMP (lbasename (pst->filename), name) == 0)
+       return (pst);
+    }
+
+  return (NULL);
+}
+\f
+/* Mangle a GDB method stub type.  This actually reassembles the pieces of the
+   full method name, which consist of the class name (from T), the unadorned
+   method name from METHOD_ID, and the signature for the specific overload,
+   specified by SIGNATURE_ID.  Note that this function is g++ specific. */
+
+char *
+gdb_mangle_name (struct type *type, int method_id, int signature_id)
+{
+  int mangled_name_len;
+  char *mangled_name;
+  struct fn_field *f = TYPE_FN_FIELDLIST1 (type, method_id);
+  struct fn_field *method = &f[signature_id];
+  char *field_name = TYPE_FN_FIELDLIST_NAME (type, method_id);
+  char *physname = TYPE_FN_FIELD_PHYSNAME (f, signature_id);
+  char *newname = type_name_no_tag (type);
+
+  /* Does the form of physname indicate that it is the full mangled name
+     of a constructor (not just the args)?  */
+  int is_full_physname_constructor;
+
+  int is_constructor;
+  int is_destructor = is_destructor_name (physname);
+  /* Need a new type prefix.  */
+  char *const_prefix = method->is_const ? "C" : "";
+  char *volatile_prefix = method->is_volatile ? "V" : "";
+  char buf[20];
+  int len = (newname == NULL ? 0 : strlen (newname));
+
+  /* Nothing to do if physname already contains a fully mangled v3 abi name
+     or an operator name.  */
+  if ((physname[0] == '_' && physname[1] == 'Z')
+      || is_operator_name (field_name))
+    return xstrdup (physname);
+
+  is_full_physname_constructor = is_constructor_name (physname);
+
+  is_constructor =
+    is_full_physname_constructor || (newname && STREQ (field_name, newname));
+
+  if (!is_destructor)
+    is_destructor = (strncmp (physname, "__dt", 4) == 0);
+
+  if (is_destructor || is_full_physname_constructor)
+    {
+      mangled_name = (char *) xmalloc (strlen (physname) + 1);
+      strcpy (mangled_name, physname);
+      return mangled_name;
+    }
+
+  if (len == 0)
+    {
+      sprintf (buf, "__%s%s", const_prefix, volatile_prefix);
+    }
+  else if (physname[0] == 't' || physname[0] == 'Q')
+    {
+      /* The physname for template and qualified methods already includes
+         the class name.  */
+      sprintf (buf, "__%s%s", const_prefix, volatile_prefix);
+      newname = NULL;
+      len = 0;
+    }
+  else
+    {
+      sprintf (buf, "__%s%s%d", const_prefix, volatile_prefix, len);
+    }
+  mangled_name_len = ((is_constructor ? 0 : strlen (field_name))
+                     + strlen (buf) + len + strlen (physname) + 1);
+
+    {
+      mangled_name = (char *) xmalloc (mangled_name_len);
+      if (is_constructor)
+       mangled_name[0] = '\0';
+      else
+       strcpy (mangled_name, field_name);
+    }
+  strcat (mangled_name, buf);
+  /* If the class doesn't have a name, i.e. newname NULL, then we just
+     mangle it using 0 for the length of the class.  Thus it gets mangled
+     as something starting with `::' rather than `classname::'. */
+  if (newname != NULL)
+    strcat (mangled_name, newname);
+
+  strcat (mangled_name, physname);
+  return (mangled_name);
+}
+
+\f
+/* Initialize a symbol's mangled name.  */
+
+/* Try to initialize the demangled name for a symbol, based on the
+   language of that symbol.  If the language is set to language_auto,
+   it will attempt to find any demangling algorithm that works and
+   then set the language appropriately.  If no demangling of any kind
+   is found, the language is set back to language_unknown, so we can
+   avoid doing this work again the next time we encounter the symbol.
+   Any required space to store the name is obtained from the specified
+   obstack. */
+
+void
+symbol_init_demangled_name (struct general_symbol_info *gsymbol,
+                            struct obstack *obstack)
+{
+  char *mangled = gsymbol->name;
+  char *demangled = NULL;
+
+  if (gsymbol->language == language_unknown)
+    gsymbol->language = language_auto;
+  if (gsymbol->language == language_cplus
+      || gsymbol->language == language_auto)
+    {
+      demangled =
+        cplus_demangle (gsymbol->name, DMGL_PARAMS | DMGL_ANSI);
+      if (demangled != NULL)
+        {
+          gsymbol->language = language_cplus;
+          gsymbol->language_specific.cplus_specific.demangled_name =
+            obsavestring (demangled, strlen (demangled), obstack);
+          xfree (demangled);
+        }
+      else
+        {
+          gsymbol->language_specific.cplus_specific.demangled_name = NULL;
+        }
+    }
+  if (gsymbol->language == language_java)
+    {
+      demangled =
+        cplus_demangle (gsymbol->name,
+                        DMGL_PARAMS | DMGL_ANSI | DMGL_JAVA);
+      if (demangled != NULL)
+        {
+          gsymbol->language = language_java;
+          gsymbol->language_specific.cplus_specific.demangled_name =
+            obsavestring (demangled, strlen (demangled), obstack);
+          xfree (demangled);
+        }
+      else
+        {
+          gsymbol->language_specific.cplus_specific.demangled_name = NULL;
+        }
+    }
+#if 0
+  /* OBSOLETE if (demangled == NULL */
+  /* OBSOLETE     && (gsymbol->language == language_chill */
+  /* OBSOLETE         || gsymbol->language == language_auto)) */
+  /* OBSOLETE   { */
+  /* OBSOLETE     demangled = */
+  /* OBSOLETE       chill_demangle (gsymbol->name); */
+  /* OBSOLETE     if (demangled != NULL) */
+  /* OBSOLETE       { */
+  /* OBSOLETE         gsymbol->language = language_chill; */
+  /* OBSOLETE         gsymbol->language_specific.chill_specific.demangled_name = */
+  /* OBSOLETE           obsavestring (demangled, strlen (demangled), obstack); */
+  /* OBSOLETE         xfree (demangled); */
+  /* OBSOLETE       } */
+  /* OBSOLETE     else */
+  /* OBSOLETE       { */
+  /* OBSOLETE         gsymbol->language_specific.chill_specific.demangled_name = NULL; */
+  /* OBSOLETE       } */
+  /* OBSOLETE   } */
+#endif
+}
+
+
+\f
+
+
+/* Find which partial symtab on contains PC and SECTION.  Return 0 if none.  */
+
+struct partial_symtab *
+find_pc_sect_psymtab (CORE_ADDR pc, asection *section)
+{
+  register struct partial_symtab *pst;
+  register struct objfile *objfile;
+  struct minimal_symbol *msymbol;
+
+  /* If we know that this is not a text address, return failure.  This is
+     necessary because we loop based on texthigh and textlow, which do
+     not include the data ranges.  */
+  msymbol = lookup_minimal_symbol_by_pc_section (pc, section);
+  if (msymbol
+      && (msymbol->type == mst_data
+         || msymbol->type == mst_bss
+         || msymbol->type == mst_abs
+         || msymbol->type == mst_file_data
+         || msymbol->type == mst_file_bss))
+    return NULL;
+
+  ALL_PSYMTABS (objfile, pst)
+  {
+    if (pc >= pst->textlow && pc < pst->texthigh)
+      {
+       struct partial_symtab *tpst;
+
+       /* An objfile that has its functions reordered might have
+          many partial symbol tables containing the PC, but
+          we want the partial symbol table that contains the
+          function containing the PC.  */
+       if (!(objfile->flags & OBJF_REORDERED) &&
+           section == 0)       /* can't validate section this way */
+         return (pst);
+
+       if (msymbol == NULL)
+         return (pst);
+
+       for (tpst = pst; tpst != NULL; tpst = tpst->next)
+         {
+           if (pc >= tpst->textlow && pc < tpst->texthigh)
+             {
+               struct partial_symbol *p;
+
+               p = find_pc_sect_psymbol (tpst, pc, section);
+               if (p != NULL
+                   && SYMBOL_VALUE_ADDRESS (p)
+                   == SYMBOL_VALUE_ADDRESS (msymbol))
+                 return (tpst);
+             }
+         }
+       return (pst);
+      }
+  }
+  return (NULL);
+}
+
+/* Find which partial symtab contains PC.  Return 0 if none. 
+   Backward compatibility, no section */
+
+struct partial_symtab *
+find_pc_psymtab (CORE_ADDR pc)
+{
+  return find_pc_sect_psymtab (pc, find_pc_mapped_section (pc));
+}
+
+/* Find which partial symbol within a psymtab matches PC and SECTION.  
+   Return 0 if none.  Check all psymtabs if PSYMTAB is 0.  */
+
+struct partial_symbol *
+find_pc_sect_psymbol (struct partial_symtab *psymtab, CORE_ADDR pc,
+                     asection *section)
+{
+  struct partial_symbol *best = NULL, *p, **pp;
+  CORE_ADDR best_pc;
+
+  if (!psymtab)
+    psymtab = find_pc_sect_psymtab (pc, section);
+  if (!psymtab)
+    return 0;
+
+  /* Cope with programs that start at address 0 */
+  best_pc = (psymtab->textlow != 0) ? psymtab->textlow - 1 : 0;
+
+  /* Search the global symbols as well as the static symbols, so that
+     find_pc_partial_function doesn't use a minimal symbol and thus
+     cache a bad endaddr.  */
+  for (pp = psymtab->objfile->global_psymbols.list + psymtab->globals_offset;
+    (pp - (psymtab->objfile->global_psymbols.list + psymtab->globals_offset)
+     < psymtab->n_global_syms);
+       pp++)
+    {
+      p = *pp;
+      if (SYMBOL_NAMESPACE (p) == VAR_NAMESPACE
+         && SYMBOL_CLASS (p) == LOC_BLOCK
+         && pc >= SYMBOL_VALUE_ADDRESS (p)
+         && (SYMBOL_VALUE_ADDRESS (p) > best_pc
+             || (psymtab->textlow == 0
+                 && best_pc == 0 && SYMBOL_VALUE_ADDRESS (p) == 0)))
+       {
+         if (section)          /* match on a specific section */
+           {
+             fixup_psymbol_section (p, psymtab->objfile);
+             if (SYMBOL_BFD_SECTION (p) != section)
+               continue;
+           }
+         best_pc = SYMBOL_VALUE_ADDRESS (p);
+         best = p;
+       }
+    }
+
+  for (pp = psymtab->objfile->static_psymbols.list + psymtab->statics_offset;
+    (pp - (psymtab->objfile->static_psymbols.list + psymtab->statics_offset)
+     < psymtab->n_static_syms);
+       pp++)
+    {
+      p = *pp;
+      if (SYMBOL_NAMESPACE (p) == VAR_NAMESPACE
+         && SYMBOL_CLASS (p) == LOC_BLOCK
+         && pc >= SYMBOL_VALUE_ADDRESS (p)
+         && (SYMBOL_VALUE_ADDRESS (p) > best_pc
+             || (psymtab->textlow == 0
+                 && best_pc == 0 && SYMBOL_VALUE_ADDRESS (p) == 0)))
+       {
+         if (section)          /* match on a specific section */
+           {
+             fixup_psymbol_section (p, psymtab->objfile);
+             if (SYMBOL_BFD_SECTION (p) != section)
+               continue;
+           }
+         best_pc = SYMBOL_VALUE_ADDRESS (p);
+         best = p;
+       }
+    }
+
+  return best;
+}
+
+/* Find which partial symbol within a psymtab matches PC.  Return 0 if none.  
+   Check all psymtabs if PSYMTAB is 0.  Backwards compatibility, no section. */
+
+struct partial_symbol *
+find_pc_psymbol (struct partial_symtab *psymtab, CORE_ADDR pc)
+{
+  return find_pc_sect_psymbol (psymtab, pc, find_pc_mapped_section (pc));
+}
+\f
+/* Debug symbols usually don't have section information.  We need to dig that
+   out of the minimal symbols and stash that in the debug symbol.  */
+
+static void
+fixup_section (struct general_symbol_info *ginfo, struct objfile *objfile)
+{
+  struct minimal_symbol *msym;
+  msym = lookup_minimal_symbol (ginfo->name, NULL, objfile);
+
+  if (msym)
+    {
+      ginfo->bfd_section = SYMBOL_BFD_SECTION (msym);
+      ginfo->section = SYMBOL_SECTION (msym);
+    }
+}
+
+struct symbol *
+fixup_symbol_section (struct symbol *sym, struct objfile *objfile)
+{
+  if (!sym)
+    return NULL;
+
+  if (SYMBOL_BFD_SECTION (sym))
+    return sym;
+
+  fixup_section (&sym->ginfo, objfile);
+
+  return sym;
+}
+
+struct partial_symbol *
+fixup_psymbol_section (struct partial_symbol *psym, struct objfile *objfile)
+{
+  if (!psym)
+    return NULL;
+
+  if (SYMBOL_BFD_SECTION (psym))
+    return psym;
+
+  fixup_section (&psym->ginfo, objfile);
+
+  return psym;
+}
+
+/* Find the definition for a specified symbol name NAME
+   in namespace NAMESPACE, visible from lexical block BLOCK.
+   Returns the struct symbol pointer, or zero if no symbol is found.
+   If SYMTAB is non-NULL, store the symbol table in which the
+   symbol was found there, or NULL if not found.
+   C++: if IS_A_FIELD_OF_THIS is nonzero on entry, check to see if
+   NAME is a field of the current implied argument `this'.  If so set
+   *IS_A_FIELD_OF_THIS to 1, otherwise set it to zero. 
+   BLOCK_FOUND is set to the block in which NAME is found (in the case of
+   a field of `this', value_of_this sets BLOCK_FOUND to the proper value.) */
+
+/* This function has a bunch of loops in it and it would seem to be
+   attractive to put in some QUIT's (though I'm not really sure
+   whether it can run long enough to be really important).  But there
+   are a few calls for which it would appear to be bad news to quit
+   out of here: find_proc_desc in alpha-tdep.c and mips-tdep.c, and
+   nindy_frame_chain_valid in nindy-tdep.c.  (Note that there is C++
+   code below which can error(), but that probably doesn't affect
+   these calls since they are looking for a known variable and thus
+   can probably assume it will never hit the C++ code).  */
+
+struct symbol *
+lookup_symbol (const char *name, const struct block *block,
+              const namespace_enum namespace, int *is_a_field_of_this,
+              struct symtab **symtab)
+{
+  char *demangled_name = NULL;
+  const char *modified_name = NULL;
+  const char *mangled_name = NULL;
+  int needtofreename = 0;
+  struct symbol *returnval;
+
+  modified_name = name;
+
+  /* If we are using C++ language, demangle the name before doing a lookup, so
+     we can always binary search. */
+  if (current_language->la_language == language_cplus)
+    {
+      demangled_name = cplus_demangle (name, DMGL_ANSI | DMGL_PARAMS);
+      if (demangled_name)
+       {
+         mangled_name = name;
+         modified_name = demangled_name;
+         needtofreename = 1;
+       }
+    }
+
+  if (case_sensitivity == case_sensitive_off)
+    {
+      char *copy;
+      int len, i;
+
+      len = strlen (name);
+      copy = (char *) alloca (len + 1);
+      for (i= 0; i < len; i++)
+        copy[i] = tolower (name[i]);
+      copy[len] = 0;
+      modified_name = copy;
+    }
+
+  returnval = lookup_symbol_aux (modified_name, mangled_name, block,
+                                namespace, is_a_field_of_this, symtab);
+  if (needtofreename)
+    xfree (demangled_name);
+
+  return returnval;     
+}
+
+static struct symbol *
+lookup_symbol_aux (const char *name, const char *mangled_name,
+                  const struct block *block, const namespace_enum namespace,
+                  int *is_a_field_of_this, struct symtab **symtab)
+{
+  register struct symbol *sym;
+  register struct symtab *s = NULL;
+  register struct partial_symtab *ps;
+  register struct blockvector *bv;
+  register struct objfile *objfile = NULL;
+  register struct block *b;
+  register struct minimal_symbol *msymbol;
+
+
+  /* Search specified block and its superiors.  */
+
+  while (block != 0)
+    {
+      sym = lookup_block_symbol (block, name, mangled_name, namespace);
+      if (sym)
+       {
+         block_found = block;
+         if (symtab != NULL)
+           {
+             /* Search the list of symtabs for one which contains the
+                address of the start of this block.  */
+             ALL_SYMTABS (objfile, s)
+             {
+               bv = BLOCKVECTOR (s);
+               b = BLOCKVECTOR_BLOCK (bv, GLOBAL_BLOCK);
+               if (BLOCK_START (b) <= BLOCK_START (block)
+                   && BLOCK_END (b) > BLOCK_START (block))
+                 goto found;
+             }
+           found:
+             *symtab = s;
+           }
+
+         return fixup_symbol_section (sym, objfile);
+       }
+      block = BLOCK_SUPERBLOCK (block);
+    }
+
+  /* FIXME: this code is never executed--block is always NULL at this
+     point.  What is it trying to do, anyway?  We already should have
+     checked the STATIC_BLOCK above (it is the superblock of top-level
+     blocks).  Why is VAR_NAMESPACE special-cased?  */
+  /* Don't need to mess with the psymtabs; if we have a block,
+     that file is read in.  If we don't, then we deal later with
+     all the psymtab stuff that needs checking.  */
+  /* Note (RT): The following never-executed code looks unnecessary to me also.
+   * If we change the code to use the original (passed-in)
+   * value of 'block', we could cause it to execute, but then what
+   * would it do? The STATIC_BLOCK of the symtab containing the passed-in
+   * 'block' was already searched by the above code. And the STATIC_BLOCK's
+   * of *other* symtabs (those files not containing 'block' lexically)
+   * should not contain 'block' address-wise. So we wouldn't expect this
+   * code to find any 'sym''s that were not found above. I vote for 
+   * deleting the following paragraph of code.
+   */
+  if (namespace == VAR_NAMESPACE && block != NULL)
+    {
+      struct block *b;
+      /* Find the right symtab.  */
+      ALL_SYMTABS (objfile, s)
+      {
+       bv = BLOCKVECTOR (s);
+       b = BLOCKVECTOR_BLOCK (bv, STATIC_BLOCK);
+       if (BLOCK_START (b) <= BLOCK_START (block)
+           && BLOCK_END (b) > BLOCK_START (block))
+         {
+           sym = lookup_block_symbol (b, name, mangled_name, VAR_NAMESPACE);
+           if (sym)
+             {
+               block_found = b;
+               if (symtab != NULL)
+                 *symtab = s;
+               return fixup_symbol_section (sym, objfile);
+             }
+         }
+      }
+    }
+
+
+  /* C++: If requested to do so by the caller, 
+     check to see if NAME is a field of `this'. */
+  if (is_a_field_of_this)
+    {
+      struct value *v = value_of_this (0);
+
+      *is_a_field_of_this = 0;
+      if (v && check_field (v, name))
+       {
+         *is_a_field_of_this = 1;
+         if (symtab != NULL)
+           *symtab = NULL;
+         return NULL;
+       }
+    }
+
+  /* Now search all global blocks.  Do the symtab's first, then
+     check the psymtab's. If a psymtab indicates the existence
+     of the desired name as a global, then do psymtab-to-symtab
+     conversion on the fly and return the found symbol. */
+
+  ALL_SYMTABS (objfile, s)
+  {
+    bv = BLOCKVECTOR (s);
+    block = BLOCKVECTOR_BLOCK (bv, GLOBAL_BLOCK);
+    sym = lookup_block_symbol (block, name, mangled_name, namespace);
+    if (sym)
+      {
+       block_found = block;
+       if (symtab != NULL)
+         *symtab = s;
+       return fixup_symbol_section (sym, objfile);
+      }
+  }
+
+#ifndef HPUXHPPA
+
+  /* Check for the possibility of the symbol being a function or
+     a mangled variable that is stored in one of the minimal symbol tables.
+     Eventually, all global symbols might be resolved in this way.  */
+
+  if (namespace == VAR_NAMESPACE)
+    {
+      msymbol = lookup_minimal_symbol (name, NULL, NULL);
+      if (msymbol != NULL)
+       {
+         s = find_pc_sect_symtab (SYMBOL_VALUE_ADDRESS (msymbol),
+                                  SYMBOL_BFD_SECTION (msymbol));
+         if (s != NULL)
+           {
+             /* This is a function which has a symtab for its address.  */
+             bv = BLOCKVECTOR (s);
+             block = BLOCKVECTOR_BLOCK (bv, GLOBAL_BLOCK);
+
+              /* This call used to pass `SYMBOL_NAME (msymbol)' as the
+                 `name' argument to lookup_block_symbol.  But the name
+                 of a minimal symbol is always mangled, so that seems
+                 to be clearly the wrong thing to pass as the
+                 unmangled name.  */
+             sym = lookup_block_symbol (block, name, mangled_name, namespace);
+             /* We kept static functions in minimal symbol table as well as
+                in static scope. We want to find them in the symbol table. */
+             if (!sym)
+               {
+                 block = BLOCKVECTOR_BLOCK (bv, STATIC_BLOCK);
+                 sym = lookup_block_symbol (block, name,
+                                             mangled_name, namespace);
+               }
+
+             /* sym == 0 if symbol was found in the minimal symbol table
+                but not in the symtab.
+                Return 0 to use the msymbol definition of "foo_".
+
+                This happens for Fortran  "foo_" symbols,
+                which are "foo" in the symtab.
+
+                This can also happen if "asm" is used to make a
+                regular symbol but not a debugging symbol, e.g.
+                asm(".globl _main");
+                asm("_main:");
+              */
+
+             if (symtab != NULL)
+               *symtab = s;
+             return fixup_symbol_section (sym, objfile);
+           }
+         else if (MSYMBOL_TYPE (msymbol) != mst_text
+                  && MSYMBOL_TYPE (msymbol) != mst_file_text
+                  && !STREQ (name, SYMBOL_NAME (msymbol)))
+           {
+             /* This is a mangled variable, look it up by its
+                mangled name.  */
+             return lookup_symbol_aux (SYMBOL_NAME (msymbol), mangled_name, block,
+                                       namespace, is_a_field_of_this, symtab);
+           }
+         /* There are no debug symbols for this file, or we are looking
+            for an unmangled variable.
+            Try to find a matching static symbol below. */
+       }
+    }
+
+#endif
+
+  ALL_PSYMTABS (objfile, ps)
+  {
+    if (!ps->readin && lookup_partial_symbol (ps, name, 1, namespace))
+      {
+       s = PSYMTAB_TO_SYMTAB (ps);
+       bv = BLOCKVECTOR (s);
+       block = BLOCKVECTOR_BLOCK (bv, GLOBAL_BLOCK);
+       sym = lookup_block_symbol (block, name, mangled_name, namespace);
+       if (!sym)
+         {
+           /* This shouldn't be necessary, but as a last resort
+            * try looking in the statics even though the psymtab
+            * claimed the symbol was global. It's possible that
+            * the psymtab gets it wrong in some cases.
+            */
+           block = BLOCKVECTOR_BLOCK (bv, STATIC_BLOCK);
+           sym = lookup_block_symbol (block, name, mangled_name, namespace);
+           if (!sym)
+             error ("Internal: global symbol `%s' found in %s psymtab but not in symtab.\n\
+%s may be an inlined function, or may be a template function\n\
+(if a template, try specifying an instantiation: %s<type>).",
+                    name, ps->filename, name, name);
+         }
+       if (symtab != NULL)
+         *symtab = s;
+       return fixup_symbol_section (sym, objfile);
+      }
+  }
+
+  /* Now search all static file-level symbols.
+     Not strictly correct, but more useful than an error.
+     Do the symtabs first, then check the psymtabs.
+     If a psymtab indicates the existence
+     of the desired name as a file-level static, then do psymtab-to-symtab
+     conversion on the fly and return the found symbol. */
+
+  ALL_SYMTABS (objfile, s)
+  {
+    bv = BLOCKVECTOR (s);
+    block = BLOCKVECTOR_BLOCK (bv, STATIC_BLOCK);
+    sym = lookup_block_symbol (block, name, mangled_name, namespace);
+    if (sym)
+      {
+       block_found = block;
+       if (symtab != NULL)
+         *symtab = s;
+       return fixup_symbol_section (sym, objfile);
+      }
+  }
+
+  ALL_PSYMTABS (objfile, ps)
+  {
+    if (!ps->readin && lookup_partial_symbol (ps, name, 0, namespace))
+      {
+       s = PSYMTAB_TO_SYMTAB (ps);
+       bv = BLOCKVECTOR (s);
+       block = BLOCKVECTOR_BLOCK (bv, STATIC_BLOCK);
+       sym = lookup_block_symbol (block, name, mangled_name, namespace);
+       if (!sym)
+         {
+           /* This shouldn't be necessary, but as a last resort
+            * try looking in the globals even though the psymtab
+            * claimed the symbol was static. It's possible that
+            * the psymtab gets it wrong in some cases.
+            */
+           block = BLOCKVECTOR_BLOCK (bv, GLOBAL_BLOCK);
+           sym = lookup_block_symbol (block, name, mangled_name, namespace);
+           if (!sym)
+             error ("Internal: static symbol `%s' found in %s psymtab but not in symtab.\n\
+%s may be an inlined function, or may be a template function\n\
+(if a template, try specifying an instantiation: %s<type>).",
+                    name, ps->filename, name, name);
+         }
+       if (symtab != NULL)
+         *symtab = s;
+       return fixup_symbol_section (sym, objfile);
+      }
+  }
+
+#ifdef HPUXHPPA
+
+  /* Check for the possibility of the symbol being a function or
+     a global variable that is stored in one of the minimal symbol tables.
+     The "minimal symbol table" is built from linker-supplied info.
+
+     RT: I moved this check to last, after the complete search of
+     the global (p)symtab's and static (p)symtab's. For HP-generated
+     symbol tables, this check was causing a premature exit from
+     lookup_symbol with NULL return, and thus messing up symbol lookups
+     of things like "c::f". It seems to me a check of the minimal
+     symbol table ought to be a last resort in any case. I'm vaguely
+     worried about the comment below which talks about FORTRAN routines "foo_"
+     though... is it saying we need to do the "minsym" check before
+     the static check in this case? 
+   */
+
+  if (namespace == VAR_NAMESPACE)
+    {
+      msymbol = lookup_minimal_symbol (name, NULL, NULL);
+      if (msymbol != NULL)
+       {
+         /* OK, we found a minimal symbol in spite of not
+          * finding any symbol. There are various possible
+          * explanations for this. One possibility is the symbol
+          * exists in code not compiled -g. Another possibility
+          * is that the 'psymtab' isn't doing its job.
+          * A third possibility, related to #2, is that we were confused 
+          * by name-mangling. For instance, maybe the psymtab isn't
+          * doing its job because it only know about demangled
+          * names, but we were given a mangled name...
+          */
+
+         /* We first use the address in the msymbol to try to
+          * locate the appropriate symtab. Note that find_pc_symtab()
+          * has a side-effect of doing psymtab-to-symtab expansion,
+          * for the found symtab.
+          */
+         s = find_pc_symtab (SYMBOL_VALUE_ADDRESS (msymbol));
+         if (s != NULL)
+           {
+             bv = BLOCKVECTOR (s);
+             block = BLOCKVECTOR_BLOCK (bv, GLOBAL_BLOCK);
+              /* This call used to pass `SYMBOL_NAME (msymbol)' as the
+                 `name' argument to lookup_block_symbol.  But the name
+                 of a minimal symbol is always mangled, so that seems
+                 to be clearly the wrong thing to pass as the
+                 unmangled name.  */
+             sym = lookup_block_symbol (block, name, mangled_name, namespace);
+             /* We kept static functions in minimal symbol table as well as
+                in static scope. We want to find them in the symbol table. */
+             if (!sym)
+               {
+                 block = BLOCKVECTOR_BLOCK (bv, STATIC_BLOCK);
+                 sym = lookup_block_symbol (block, name,
+                                             mangled_name, namespace);
+               }
+             /* If we found one, return it */
+             if (sym)
+               {
+                 if (symtab != NULL)
+                   *symtab = s;
+                 return sym;
+               }
+
+             /* If we get here with sym == 0, the symbol was 
+                found in the minimal symbol table
+                but not in the symtab.
+                Fall through and return 0 to use the msymbol 
+                definition of "foo_".
+                (Note that outer code generally follows up a call
+                to this routine with a call to lookup_minimal_symbol(),
+                so a 0 return means we'll just flow into that other routine).
+
+                This happens for Fortran  "foo_" symbols,
+                which are "foo" in the symtab.
+
+                This can also happen if "asm" is used to make a
+                regular symbol but not a debugging symbol, e.g.
+                asm(".globl _main");
+                asm("_main:");
+              */
+           }
+
+         /* If the lookup-by-address fails, try repeating the
+          * entire lookup process with the symbol name from
+          * the msymbol (if different from the original symbol name).
+          */
+         else if (MSYMBOL_TYPE (msymbol) != mst_text
+                  && MSYMBOL_TYPE (msymbol) != mst_file_text
+                  && !STREQ (name, SYMBOL_NAME (msymbol)))
+           {
+             return lookup_symbol_aux (SYMBOL_NAME (msymbol), mangled_name,
+                                       block, namespace, is_a_field_of_this,
+                                       symtab);
+           }
+       }
+    }
+
+#endif
+
+  if (symtab != NULL)
+    *symtab = NULL;
+  return 0;
+}
+                                                               
+/* Look, in partial_symtab PST, for symbol NAME.  Check the global
+   symbols if GLOBAL, the static symbols if not */
+
+static struct partial_symbol *
+lookup_partial_symbol (struct partial_symtab *pst, const char *name, int global,
+                      namespace_enum namespace)
+{
+  struct partial_symbol *temp;
+  struct partial_symbol **start, **psym;
+  struct partial_symbol **top, **bottom, **center;
+  int length = (global ? pst->n_global_syms : pst->n_static_syms);
+  int do_linear_search = 1;
+  
+  if (length == 0)
+    {
+      return (NULL);
+    }
+  start = (global ?
+          pst->objfile->global_psymbols.list + pst->globals_offset :
+          pst->objfile->static_psymbols.list + pst->statics_offset);
+  
+  if (global)                  /* This means we can use a binary search. */
+    {
+      do_linear_search = 0;
+
+      /* Binary search.  This search is guaranteed to end with center
+         pointing at the earliest partial symbol with the correct
+         name.  At that point *all* partial symbols with that name
+         will be checked against the correct namespace. */
+
+      bottom = start;
+      top = start + length - 1;
+      while (top > bottom)
+       {
+         center = bottom + (top - bottom) / 2;
+         if (!(center < top))
+           internal_error (__FILE__, __LINE__, "failed internal consistency check");
+         if (!do_linear_search
+             && (SYMBOL_LANGUAGE (*center) == language_java))
+           {
+             do_linear_search = 1;
+           }
+         if (strcmp (SYMBOL_SOURCE_NAME (*center), name) >= 0)
+           {
+             top = center;
+           }
+         else
+           {
+             bottom = center + 1;
+           }
+       }
+      if (!(top == bottom))
+       internal_error (__FILE__, __LINE__, "failed internal consistency check");
+
+      /* djb - 2000-06-03 - Use SYMBOL_MATCHES_NAME, not a strcmp, so
+        we don't have to force a linear search on C++. Probably holds true
+        for JAVA as well, no way to check.*/
+      while (SYMBOL_MATCHES_NAME (*top,name))
+       {
+         if (SYMBOL_NAMESPACE (*top) == namespace)
+           {
+                 return (*top);
+           }
+         top++;
+       }
+    }
+
+  /* Can't use a binary search or else we found during the binary search that
+     we should also do a linear search. */
+
+  if (do_linear_search)
+    {                  
+      for (psym = start; psym < start + length; psym++)
+       {
+         if (namespace == SYMBOL_NAMESPACE (*psym))
+           {
+             if (SYMBOL_MATCHES_NAME (*psym, name))
+               {
+                 return (*psym);
+               }
+           }
+       }
+    }
+
+  return (NULL);
+}
+
+/* Look up a type named NAME in the struct_namespace.  The type returned
+   must not be opaque -- i.e., must have at least one field defined
+
+   This code was modelled on lookup_symbol -- the parts not relevant to looking
+   up types were just left out.  In particular it's assumed here that types
+   are available in struct_namespace and only at file-static or global blocks. */
+
+
+struct type *
+lookup_transparent_type (const char *name)
+{
+  register struct symbol *sym;
+  register struct symtab *s = NULL;
+  register struct partial_symtab *ps;
+  struct blockvector *bv;
+  register struct objfile *objfile;
+  register struct block *block;
+
+  /* Now search all the global symbols.  Do the symtab's first, then
+     check the psymtab's. If a psymtab indicates the existence
+     of the desired name as a global, then do psymtab-to-symtab
+     conversion on the fly and return the found symbol.  */
+
+  ALL_SYMTABS (objfile, s)
+  {
+    bv = BLOCKVECTOR (s);
+    block = BLOCKVECTOR_BLOCK (bv, GLOBAL_BLOCK);
+    sym = lookup_block_symbol (block, name, NULL, STRUCT_NAMESPACE);
+    if (sym && !TYPE_IS_OPAQUE (SYMBOL_TYPE (sym)))
+      {
+       return SYMBOL_TYPE (sym);
+      }
+  }
+
+  ALL_PSYMTABS (objfile, ps)
+  {
+    if (!ps->readin && lookup_partial_symbol (ps, name, 1, STRUCT_NAMESPACE))
+      {
+       s = PSYMTAB_TO_SYMTAB (ps);
+       bv = BLOCKVECTOR (s);
+       block = BLOCKVECTOR_BLOCK (bv, GLOBAL_BLOCK);
+       sym = lookup_block_symbol (block, name, NULL, STRUCT_NAMESPACE);
+       if (!sym)
+         {
+           /* This shouldn't be necessary, but as a last resort
+            * try looking in the statics even though the psymtab
+            * claimed the symbol was global. It's possible that
+            * the psymtab gets it wrong in some cases.
+            */
+           block = BLOCKVECTOR_BLOCK (bv, STATIC_BLOCK);
+           sym = lookup_block_symbol (block, name, NULL, STRUCT_NAMESPACE);
+           if (!sym)
+             error ("Internal: global symbol `%s' found in %s psymtab but not in symtab.\n\
+%s may be an inlined function, or may be a template function\n\
+(if a template, try specifying an instantiation: %s<type>).",
+                    name, ps->filename, name, name);
+         }
+       if (!TYPE_IS_OPAQUE (SYMBOL_TYPE (sym)))
+         return SYMBOL_TYPE (sym);
+      }
+  }
+
+  /* Now search the static file-level symbols.
+     Not strictly correct, but more useful than an error.
+     Do the symtab's first, then
+     check the psymtab's. If a psymtab indicates the existence
+     of the desired name as a file-level static, then do psymtab-to-symtab
+     conversion on the fly and return the found symbol.
+   */
+
+  ALL_SYMTABS (objfile, s)
+  {
+    bv = BLOCKVECTOR (s);
+    block = BLOCKVECTOR_BLOCK (bv, STATIC_BLOCK);
+    sym = lookup_block_symbol (block, name, NULL, STRUCT_NAMESPACE);
+    if (sym && !TYPE_IS_OPAQUE (SYMBOL_TYPE (sym)))
+      {
+       return SYMBOL_TYPE (sym);
+      }
+  }
+
+  ALL_PSYMTABS (objfile, ps)
+  {
+    if (!ps->readin && lookup_partial_symbol (ps, name, 0, STRUCT_NAMESPACE))
+      {
+       s = PSYMTAB_TO_SYMTAB (ps);
+       bv = BLOCKVECTOR (s);
+       block = BLOCKVECTOR_BLOCK (bv, STATIC_BLOCK);
+       sym = lookup_block_symbol (block, name, NULL, STRUCT_NAMESPACE);
+       if (!sym)
+         {
+           /* This shouldn't be necessary, but as a last resort
+            * try looking in the globals even though the psymtab
+            * claimed the symbol was static. It's possible that
+            * the psymtab gets it wrong in some cases.
+            */
+           block = BLOCKVECTOR_BLOCK (bv, GLOBAL_BLOCK);
+           sym = lookup_block_symbol (block, name, NULL, STRUCT_NAMESPACE);
+           if (!sym)
+             error ("Internal: static symbol `%s' found in %s psymtab but not in symtab.\n\
+%s may be an inlined function, or may be a template function\n\
+(if a template, try specifying an instantiation: %s<type>).",
+                    name, ps->filename, name, name);
+         }
+       if (!TYPE_IS_OPAQUE (SYMBOL_TYPE (sym)))
+         return SYMBOL_TYPE (sym);
+      }
+  }
+  return (struct type *) 0;
+}
+
+
+/* Find the psymtab containing main(). */
+/* FIXME:  What about languages without main() or specially linked
+   executables that have no main() ? */
+
+struct partial_symtab *
+find_main_psymtab (void)
+{
+  register struct partial_symtab *pst;
+  register struct objfile *objfile;
+
+  ALL_PSYMTABS (objfile, pst)
+  {
+    if (lookup_partial_symbol (pst, main_name (), 1, VAR_NAMESPACE))
+      {
+       return (pst);
+      }
+  }
+  return (NULL);
+}
+
+/* Search BLOCK for symbol NAME in NAMESPACE.
+
+   Note that if NAME is the demangled form of a C++ symbol, we will fail
+   to find a match during the binary search of the non-encoded names, but
+   for now we don't worry about the slight inefficiency of looking for
+   a match we'll never find, since it will go pretty quick.  Once the
+   binary search terminates, we drop through and do a straight linear
+   search on the symbols.  Each symbol which is marked as being a C++
+   symbol (language_cplus set) has both the encoded and non-encoded names
+   tested for a match.
+
+   If MANGLED_NAME is non-NULL, verify that any symbol we find has this
+   particular mangled name.
+*/
+
+struct symbol *
+lookup_block_symbol (register const struct block *block, const char *name,
+                    const char *mangled_name,
+                    const namespace_enum namespace)
+{
+  register int bot, top, inc;
+  register struct symbol *sym;
+  register struct symbol *sym_found = NULL;
+  register int do_linear_search = 1;
+
+  if (BLOCK_HASHTABLE (block))
+    {
+      unsigned int hash_index;
+      hash_index = msymbol_hash_iw (name);
+      hash_index = hash_index % BLOCK_BUCKETS (block);
+      for (sym = BLOCK_BUCKET (block, hash_index); sym; sym = sym->hash_next)
+       {
+         if (SYMBOL_NAMESPACE (sym) == namespace 
+             && (mangled_name
+                 ? strcmp (SYMBOL_NAME (sym), mangled_name) == 0
+                 : SYMBOL_MATCHES_NAME (sym, name)))
+           return sym;
+       }
+      return NULL;
+    }
+
+  /* If the blocks's symbols were sorted, start with a binary search.  */
+
+  if (BLOCK_SHOULD_SORT (block))
+    {
+      /* Reset the linear search flag so if the binary search fails, we
+         won't do the linear search once unless we find some reason to
+         do so */
+
+      do_linear_search = 0;
+      top = BLOCK_NSYMS (block);
+      bot = 0;
+
+      /* Advance BOT to not far before the first symbol whose name is NAME. */
+
+      while (1)
+       {
+         inc = (top - bot + 1);
+         /* No need to keep binary searching for the last few bits worth.  */
+         if (inc < 4)
+           {
+             break;
+           }
+         inc = (inc >> 1) + bot;
+         sym = BLOCK_SYM (block, inc);
+         if (!do_linear_search && (SYMBOL_LANGUAGE (sym) == language_java))
+           {
+             do_linear_search = 1;
+           }
+         if (SYMBOL_SOURCE_NAME (sym)[0] < name[0])
+           {
+             bot = inc;
+           }
+         else if (SYMBOL_SOURCE_NAME (sym)[0] > name[0])
+           {
+             top = inc;
+           }
+         else if (strcmp (SYMBOL_SOURCE_NAME (sym), name) < 0)
+           {
+             bot = inc;
+           }
+         else
+           {
+             top = inc;
+           }
+       }
+
+      /* Now scan forward until we run out of symbols, find one whose
+         name is greater than NAME, or find one we want.  If there is
+         more than one symbol with the right name and namespace, we
+         return the first one; I believe it is now impossible for us
+         to encounter two symbols with the same name and namespace
+         here, because blocks containing argument symbols are no
+         longer sorted.  The exception is for C++, where multiple functions
+        (cloned constructors / destructors, in particular) can have
+        the same demangled name.  So if we have a particular
+        mangled name to match, try to do so.  */
+
+      top = BLOCK_NSYMS (block);
+      while (bot < top)
+       {
+         sym = BLOCK_SYM (block, bot);
+         if (SYMBOL_NAMESPACE (sym) == namespace
+             && (mangled_name
+                 ? strcmp (SYMBOL_NAME (sym), mangled_name) == 0
+                 : SYMBOL_MATCHES_NAME (sym, name)))
+           {
+             return sym;
+           }
+          if (SYMBOL_SOURCE_NAME (sym)[0] > name[0])
+            {
+              break;
+            }
+         bot++;
+       }
+    }
+
+  /* Here if block isn't sorted, or we fail to find a match during the
+     binary search above.  If during the binary search above, we find a
+     symbol which is a Java symbol, then we have re-enabled the linear
+     search flag which was reset when starting the binary search.
+
+     This loop is equivalent to the loop above, but hacked greatly for speed.
+
+     Note that parameter symbols do not always show up last in the
+     list; this loop makes sure to take anything else other than
+     parameter symbols first; it only uses parameter symbols as a
+     last resort.  Note that this only takes up extra computation
+     time on a match.  */
+
+  if (do_linear_search)
+    {
+      top = BLOCK_NSYMS (block);
+      bot = 0;
+      while (bot < top)
+       {
+         sym = BLOCK_SYM (block, bot);
+         if (SYMBOL_NAMESPACE (sym) == namespace
+             && (mangled_name
+                 ? strcmp (SYMBOL_NAME (sym), mangled_name) == 0
+                 : SYMBOL_MATCHES_NAME (sym, name)))
+           {
+             /* If SYM has aliases, then use any alias that is active
+                at the current PC.  If no alias is active at the current
+                PC, then use the main symbol.
+
+                ?!? Is checking the current pc correct?  Is this routine
+                ever called to look up a symbol from another context?
+
+                FIXME: No, it's not correct.  If someone sets a
+                conditional breakpoint at an address, then the
+                breakpoint's `struct expression' should refer to the
+                `struct symbol' appropriate for the breakpoint's
+                address, which may not be the PC.
+
+                Even if it were never called from another context,
+                it's totally bizarre for lookup_symbol's behavior to
+                depend on the value of the inferior's current PC.  We
+                should pass in the appropriate PC as well as the
+                block.  The interface to lookup_symbol should change
+                to require the caller to provide a PC.  */
+
+             if (SYMBOL_ALIASES (sym))
+               sym = find_active_alias (sym, read_pc ());
+
+             sym_found = sym;
+             if (SYMBOL_CLASS (sym) != LOC_ARG &&
+                 SYMBOL_CLASS (sym) != LOC_LOCAL_ARG &&
+                 SYMBOL_CLASS (sym) != LOC_REF_ARG &&
+                 SYMBOL_CLASS (sym) != LOC_REGPARM &&
+                 SYMBOL_CLASS (sym) != LOC_REGPARM_ADDR &&
+                 SYMBOL_CLASS (sym) != LOC_BASEREG_ARG)
+               {
+                 break;
+               }
+           }
+         bot++;
+       }
+    }
+  return (sym_found);          /* Will be NULL if not found. */
+}
+
+/* Given a main symbol SYM and ADDR, search through the alias
+   list to determine if an alias is active at ADDR and return
+   the active alias.
+
+   If no alias is active, then return SYM.  */
+
+static struct symbol *
+find_active_alias (struct symbol *sym, CORE_ADDR addr)
+{
+  struct range_list *r;
+  struct alias_list *aliases;
+
+  /* If we have aliases, check them first.  */
+  aliases = SYMBOL_ALIASES (sym);
+
+  while (aliases)
+    {
+      if (!SYMBOL_RANGES (aliases->sym))
+       return aliases->sym;
+      for (r = SYMBOL_RANGES (aliases->sym); r; r = r->next)
+       {
+         if (r->start <= addr && r->end > addr)
+           return aliases->sym;
+       }
+      aliases = aliases->next;
+    }
+
+  /* Nothing found, return the main symbol.  */
+  return sym;
+}
+\f
+
+/* Return the symbol for the function which contains a specified
+   lexical block, described by a struct block BL.  */
+
+struct symbol *
+block_function (struct block *bl)
+{
+  while (BLOCK_FUNCTION (bl) == 0 && BLOCK_SUPERBLOCK (bl) != 0)
+    bl = BLOCK_SUPERBLOCK (bl);
+
+  return BLOCK_FUNCTION (bl);
+}
+
+/* Find the symtab associated with PC and SECTION.  Look through the
+   psymtabs and read in another symtab if necessary. */
+
+struct symtab *
+find_pc_sect_symtab (CORE_ADDR pc, asection *section)
+{
+  register struct block *b;
+  struct blockvector *bv;
+  register struct symtab *s = NULL;
+  register struct symtab *best_s = NULL;
+  register struct partial_symtab *ps;
+  register struct objfile *objfile;
+  CORE_ADDR distance = 0;
+  struct minimal_symbol *msymbol;
+
+  /* If we know that this is not a text address, return failure.  This is
+     necessary because we loop based on the block's high and low code
+     addresses, which do not include the data ranges, and because
+     we call find_pc_sect_psymtab which has a similar restriction based
+     on the partial_symtab's texthigh and textlow.  */
+  msymbol = lookup_minimal_symbol_by_pc_section (pc, section);
+  if (msymbol
+      && (msymbol->type == mst_data
+         || msymbol->type == mst_bss
+         || msymbol->type == mst_abs
+         || msymbol->type == mst_file_data
+         || msymbol->type == mst_file_bss))
+    return NULL;
+
+  /* Search all symtabs for the one whose file contains our address, and which
+     is the smallest of all the ones containing the address.  This is designed
+     to deal with a case like symtab a is at 0x1000-0x2000 and 0x3000-0x4000
+     and symtab b is at 0x2000-0x3000.  So the GLOBAL_BLOCK for a is from
+     0x1000-0x4000, but for address 0x2345 we want to return symtab b.
+
+     This happens for native ecoff format, where code from included files
+     gets its own symtab. The symtab for the included file should have
+     been read in already via the dependency mechanism.
+     It might be swifter to create several symtabs with the same name
+     like xcoff does (I'm not sure).
+
+     It also happens for objfiles that have their functions reordered.
+     For these, the symtab we are looking for is not necessarily read in.  */
+
+  ALL_SYMTABS (objfile, s)
+  {
+    bv = BLOCKVECTOR (s);
+    b = BLOCKVECTOR_BLOCK (bv, GLOBAL_BLOCK);
+
+    if (BLOCK_START (b) <= pc
+       && BLOCK_END (b) > pc
+       && (distance == 0
+           || BLOCK_END (b) - BLOCK_START (b) < distance))
+      {
+       /* For an objfile that has its functions reordered,
+          find_pc_psymtab will find the proper partial symbol table
+          and we simply return its corresponding symtab.  */
+       /* In order to better support objfiles that contain both
+          stabs and coff debugging info, we continue on if a psymtab
+          can't be found. */
+       if ((objfile->flags & OBJF_REORDERED) && objfile->psymtabs)
+         {
+           ps = find_pc_sect_psymtab (pc, section);
+           if (ps)
+             return PSYMTAB_TO_SYMTAB (ps);
+         }
+       if (section != 0)
+         {
+           int i;
+           struct symbol *sym = NULL;
+
+           ALL_BLOCK_SYMBOLS (b, i, sym)
+             {
+               fixup_symbol_section (sym, objfile);
+               if (section == SYMBOL_BFD_SECTION (sym))
+                 break;
+             }
+           if ((i >= BLOCK_BUCKETS (b)) && (sym == NULL))
+             continue;         /* no symbol in this symtab matches section */
+         }
+       distance = BLOCK_END (b) - BLOCK_START (b);
+       best_s = s;
+      }
+  }
+
+  if (best_s != NULL)
+    return (best_s);
+
+  s = NULL;
+  ps = find_pc_sect_psymtab (pc, section);
+  if (ps)
+    {
+      if (ps->readin)
+       /* Might want to error() here (in case symtab is corrupt and
+          will cause a core dump), but maybe we can successfully
+          continue, so let's not.  */
+       warning ("\
+(Internal error: pc 0x%s in read in psymtab, but not in symtab.)\n",
+                paddr_nz (pc));
+      s = PSYMTAB_TO_SYMTAB (ps);
+    }
+  return (s);
+}
+
+/* Find the symtab associated with PC.  Look through the psymtabs and
+   read in another symtab if necessary.  Backward compatibility, no section */
+
+struct symtab *
+find_pc_symtab (CORE_ADDR pc)
+{
+  return find_pc_sect_symtab (pc, find_pc_mapped_section (pc));
+}
+\f
+
+#if 0
+
+/* Find the closest symbol value (of any sort -- function or variable)
+   for a given address value.  Slow but complete.  (currently unused,
+   mainly because it is too slow.  We could fix it if each symtab and
+   psymtab had contained in it the addresses ranges of each of its
+   sections, which also would be required to make things like "info
+   line *0x2345" cause psymtabs to be converted to symtabs).  */
+
+struct symbol *
+find_addr_symbol (CORE_ADDR addr, struct symtab **symtabp, CORE_ADDR *symaddrp)
+{
+  struct symtab *symtab, *best_symtab;
+  struct objfile *objfile;
+  register int bot, top;
+  register struct symbol *sym;
+  register CORE_ADDR sym_addr;
+  struct block *block;
+  int blocknum;
+
+  /* Info on best symbol seen so far */
+
+  register CORE_ADDR best_sym_addr = 0;
+  struct symbol *best_sym = 0;
+
+  /* FIXME -- we should pull in all the psymtabs, too!  */
+  ALL_SYMTABS (objfile, symtab)
+  {
+    /* Search the global and static blocks in this symtab for
+       the closest symbol-address to the desired address.  */
+
+    for (blocknum = GLOBAL_BLOCK; blocknum <= STATIC_BLOCK; blocknum++)
+      {
+       QUIT;
+       block = BLOCKVECTOR_BLOCK (BLOCKVECTOR (symtab), blocknum);
+       ALL_BLOCK_SYMBOLS (block, bot, sym)
+         {
+           switch (SYMBOL_CLASS (sym))
+             {
+             case LOC_STATIC:
+             case LOC_LABEL:
+               sym_addr = SYMBOL_VALUE_ADDRESS (sym);
+               break;
+
+             case LOC_INDIRECT:
+               sym_addr = SYMBOL_VALUE_ADDRESS (sym);
+               /* An indirect symbol really lives at *sym_addr,
+                * so an indirection needs to be done.
+                * However, I am leaving this commented out because it's
+                * expensive, and it's possible that symbolization
+                * could be done without an active process (in
+                * case this read_memory will fail). RT
+                sym_addr = read_memory_unsigned_integer
+                (sym_addr, TARGET_PTR_BIT / TARGET_CHAR_BIT);
+                */
+               break;
+
+             case LOC_BLOCK:
+               sym_addr = BLOCK_START (SYMBOL_BLOCK_VALUE (sym));
+               break;
+
+             default:
+               continue;
+             }
+
+           if (sym_addr <= addr)
+             if (sym_addr > best_sym_addr)
+               {
+                 /* Quit if we found an exact match.  */
+                 best_sym = sym;
+                 best_sym_addr = sym_addr;
+                 best_symtab = symtab;
+                 if (sym_addr == addr)
+                   goto done;
+               }
+         }
+      }
+  }
+
+done:
+  if (symtabp)
+    *symtabp = best_symtab;
+  if (symaddrp)
+    *symaddrp = best_sym_addr;
+  return best_sym;
+}
+#endif /* 0 */
+
+/* Find the source file and line number for a given PC value and SECTION.
+   Return a structure containing a symtab pointer, a line number,
+   and a pc range for the entire source line.
+   The value's .pc field is NOT the specified pc.
+   NOTCURRENT nonzero means, if specified pc is on a line boundary,
+   use the line that ends there.  Otherwise, in that case, the line
+   that begins there is used.  */
+
+/* The big complication here is that a line may start in one file, and end just
+   before the start of another file.  This usually occurs when you #include
+   code in the middle of a subroutine.  To properly find the end of a line's PC
+   range, we must search all symtabs associated with this compilation unit, and
+   find the one whose first PC is closer than that of the next line in this
+   symtab.  */
+
+/* If it's worth the effort, we could be using a binary search.  */
+
+struct symtab_and_line
+find_pc_sect_line (CORE_ADDR pc, struct sec *section, int notcurrent)
+{
+  struct symtab *s;
+  register struct linetable *l;
+  register int len;
+  register int i;
+  register struct linetable_entry *item;
+  struct symtab_and_line val;
+  struct blockvector *bv;
+  struct minimal_symbol *msymbol;
+  struct minimal_symbol *mfunsym;
+
+  /* Info on best line seen so far, and where it starts, and its file.  */
+
+  struct linetable_entry *best = NULL;
+  CORE_ADDR best_end = 0;
+  struct symtab *best_symtab = 0;
+
+  /* Store here the first line number
+     of a file which contains the line at the smallest pc after PC.
+     If we don't find a line whose range contains PC,
+     we will use a line one less than this,
+     with a range from the start of that file to the first line's pc.  */
+  struct linetable_entry *alt = NULL;
+  struct symtab *alt_symtab = 0;
+
+  /* Info on best line seen in this file.  */
+
+  struct linetable_entry *prev;
+
+  /* If this pc is not from the current frame,
+     it is the address of the end of a call instruction.
+     Quite likely that is the start of the following statement.
+     But what we want is the statement containing the instruction.
+     Fudge the pc to make sure we get that.  */
+
+  INIT_SAL (&val);             /* initialize to zeroes */
+
+  /* It's tempting to assume that, if we can't find debugging info for
+     any function enclosing PC, that we shouldn't search for line
+     number info, either.  However, GAS can emit line number info for
+     assembly files --- very helpful when debugging hand-written
+     assembly code.  In such a case, we'd have no debug info for the
+     function, but we would have line info.  */
+
+  if (notcurrent)
+    pc -= 1;
+
+  /* elz: added this because this function returned the wrong
+     information if the pc belongs to a stub (import/export)
+     to call a shlib function. This stub would be anywhere between
+     two functions in the target, and the line info was erroneously 
+     taken to be the one of the line before the pc. 
+   */
+  /* RT: Further explanation:
+
+   * We have stubs (trampolines) inserted between procedures.
+   *
+   * Example: "shr1" exists in a shared library, and a "shr1" stub also
+   * exists in the main image.
+   *
+   * In the minimal symbol table, we have a bunch of symbols
+   * sorted by start address. The stubs are marked as "trampoline",
+   * the others appear as text. E.g.:
+   *
+   *  Minimal symbol table for main image 
+   *     main:  code for main (text symbol)
+   *     shr1: stub  (trampoline symbol)
+   *     foo:   code for foo (text symbol)
+   *     ...
+   *  Minimal symbol table for "shr1" image:
+   *     ...
+   *     shr1: code for shr1 (text symbol)
+   *     ...
+   *
+   * So the code below is trying to detect if we are in the stub
+   * ("shr1" stub), and if so, find the real code ("shr1" trampoline),
+   * and if found,  do the symbolization from the real-code address
+   * rather than the stub address.
+   *
+   * Assumptions being made about the minimal symbol table:
+   *   1. lookup_minimal_symbol_by_pc() will return a trampoline only
+   *      if we're really in the trampoline. If we're beyond it (say
+   *      we're in "foo" in the above example), it'll have a closer 
+   *      symbol (the "foo" text symbol for example) and will not
+   *      return the trampoline.
+   *   2. lookup_minimal_symbol_text() will find a real text symbol
+   *      corresponding to the trampoline, and whose address will
+   *      be different than the trampoline address. I put in a sanity
+   *      check for the address being the same, to avoid an
+   *      infinite recursion.
+   */
+  msymbol = lookup_minimal_symbol_by_pc (pc);
+  if (msymbol != NULL)
+    if (MSYMBOL_TYPE (msymbol) == mst_solib_trampoline)
+      {
+       mfunsym = lookup_minimal_symbol_text (SYMBOL_NAME (msymbol), NULL, NULL);
+       if (mfunsym == NULL)
+         /* I eliminated this warning since it is coming out
+          * in the following situation:
+          * gdb shmain // test program with shared libraries
+          * (gdb) break shr1  // function in shared lib
+          * Warning: In stub for ...
+          * In the above situation, the shared lib is not loaded yet, 
+          * so of course we can't find the real func/line info,
+          * but the "break" still works, and the warning is annoying.
+          * So I commented out the warning. RT */
+         /* warning ("In stub for %s; unable to find real function/line info", SYMBOL_NAME(msymbol)) */ ;
+       /* fall through */
+       else if (SYMBOL_VALUE (mfunsym) == SYMBOL_VALUE (msymbol))
+         /* Avoid infinite recursion */
+         /* See above comment about why warning is commented out */
+         /* warning ("In stub for %s; unable to find real function/line info", SYMBOL_NAME(msymbol)) */ ;
+       /* fall through */
+       else
+         return find_pc_line (SYMBOL_VALUE (mfunsym), 0);
+      }
+
+
+  s = find_pc_sect_symtab (pc, section);
+  if (!s)
+    {
+      /* if no symbol information, return previous pc */
+      if (notcurrent)
+       pc++;
+      val.pc = pc;
+      return val;
+    }
+
+  bv = BLOCKVECTOR (s);
+
+  /* Look at all the symtabs that share this blockvector.
+     They all have the same apriori range, that we found was right;
+     but they have different line tables.  */
+
+  for (; s && BLOCKVECTOR (s) == bv; s = s->next)
+    {
+      /* Find the best line in this symtab.  */
+      l = LINETABLE (s);
+      if (!l)
+       continue;
+      len = l->nitems;
+      if (len <= 0)
+       {
+         /* I think len can be zero if the symtab lacks line numbers
+            (e.g. gcc -g1).  (Either that or the LINETABLE is NULL;
+            I'm not sure which, and maybe it depends on the symbol
+            reader).  */
+         continue;
+       }
+
+      prev = NULL;
+      item = l->item;          /* Get first line info */
+
+      /* Is this file's first line closer than the first lines of other files?
+         If so, record this file, and its first line, as best alternate.  */
+      if (item->pc > pc && (!alt || item->pc < alt->pc))
+       {
+         alt = item;
+         alt_symtab = s;
+       }
+
+      for (i = 0; i < len; i++, item++)
+       {
+         /* Leave prev pointing to the linetable entry for the last line
+            that started at or before PC.  */
+         if (item->pc > pc)
+           break;
+
+         prev = item;
+       }
+
+      /* At this point, prev points at the line whose start addr is <= pc, and
+         item points at the next line.  If we ran off the end of the linetable
+         (pc >= start of the last line), then prev == item.  If pc < start of
+         the first line, prev will not be set.  */
+
+      /* Is this file's best line closer than the best in the other files?
+         If so, record this file, and its best line, as best so far.  */
+
+      if (prev && (!best || prev->pc > best->pc))
+       {
+         best = prev;
+         best_symtab = s;
+
+         /* Discard BEST_END if it's before the PC of the current BEST.  */
+         if (best_end <= best->pc)
+           best_end = 0;
+       }
+
+      /* If another line (denoted by ITEM) is in the linetable and its
+         PC is after BEST's PC, but before the current BEST_END, then
+        use ITEM's PC as the new best_end.  */
+      if (best && i < len && item->pc > best->pc
+          && (best_end == 0 || best_end > item->pc))
+       best_end = item->pc;
+    }
+
+  if (!best_symtab)
+    {
+      if (!alt_symtab)
+       {                       /* If we didn't find any line # info, just
+                                  return zeros.  */
+         val.pc = pc;
+       }
+      else
+       {
+         val.symtab = alt_symtab;
+         val.line = alt->line - 1;
+
+         /* Don't return line 0, that means that we didn't find the line.  */
+         if (val.line == 0)
+           ++val.line;
+
+         val.pc = BLOCK_END (BLOCKVECTOR_BLOCK (bv, GLOBAL_BLOCK));
+         val.end = alt->pc;
+       }
+    }
+  else if (best->line == 0)
+    {
+      /* If our best fit is in a range of PC's for which no line
+        number info is available (line number is zero) then we didn't
+        find any valid line information. */
+      val.pc = pc;
+    }
+  else
+    {
+      val.symtab = best_symtab;
+      val.line = best->line;
+      val.pc = best->pc;
+      if (best_end && (!alt || best_end < alt->pc))
+       val.end = best_end;
+      else if (alt)
+       val.end = alt->pc;
+      else
+       val.end = BLOCK_END (BLOCKVECTOR_BLOCK (bv, GLOBAL_BLOCK));
+    }
+  val.section = section;
+  return val;
+}
+
+/* Backward compatibility (no section) */
+
+struct symtab_and_line
+find_pc_line (CORE_ADDR pc, int notcurrent)
+{
+  asection *section;
+
+  section = find_pc_overlay (pc);
+  if (pc_in_unmapped_range (pc, section))
+    pc = overlay_mapped_address (pc, section);
+  return find_pc_sect_line (pc, section, notcurrent);
+}
+\f
+/* Find line number LINE in any symtab whose name is the same as
+   SYMTAB.
+
+   If found, return the symtab that contains the linetable in which it was
+   found, set *INDEX to the index in the linetable of the best entry
+   found, and set *EXACT_MATCH nonzero if the value returned is an
+   exact match.
+
+   If not found, return NULL.  */
+
+struct symtab *
+find_line_symtab (struct symtab *symtab, int line, int *index, int *exact_match)
+{
+  int exact;
+
+  /* BEST_INDEX and BEST_LINETABLE identify the smallest linenumber > LINE
+     so far seen.  */
+
+  int best_index;
+  struct linetable *best_linetable;
+  struct symtab *best_symtab;
+
+  /* First try looking it up in the given symtab.  */
+  best_linetable = LINETABLE (symtab);
+  best_symtab = symtab;
+  best_index = find_line_common (best_linetable, line, &exact);
+  if (best_index < 0 || !exact)
+    {
+      /* Didn't find an exact match.  So we better keep looking for
+         another symtab with the same name.  In the case of xcoff,
+         multiple csects for one source file (produced by IBM's FORTRAN
+         compiler) produce multiple symtabs (this is unavoidable
+         assuming csects can be at arbitrary places in memory and that
+         the GLOBAL_BLOCK of a symtab has a begin and end address).  */
+
+      /* BEST is the smallest linenumber > LINE so far seen,
+         or 0 if none has been seen so far.
+         BEST_INDEX and BEST_LINETABLE identify the item for it.  */
+      int best;
+
+      struct objfile *objfile;
+      struct symtab *s;
+
+      if (best_index >= 0)
+       best = best_linetable->item[best_index].line;
+      else
+       best = 0;
+
+      ALL_SYMTABS (objfile, s)
+      {
+       struct linetable *l;
+       int ind;
+
+       if (!STREQ (symtab->filename, s->filename))
+         continue;
+       l = LINETABLE (s);
+       ind = find_line_common (l, line, &exact);
+       if (ind >= 0)
+         {
+           if (exact)
+             {
+               best_index = ind;
+               best_linetable = l;
+               best_symtab = s;
+               goto done;
+             }
+           if (best == 0 || l->item[ind].line < best)
+             {
+               best = l->item[ind].line;
+               best_index = ind;
+               best_linetable = l;
+               best_symtab = s;
+             }
+         }
+      }
+    }
+done:
+  if (best_index < 0)
+    return NULL;
+
+  if (index)
+    *index = best_index;
+  if (exact_match)
+    *exact_match = exact;
+
+  return best_symtab;
+}
+\f
+/* Set the PC value for a given source file and line number and return true.
+   Returns zero for invalid line number (and sets the PC to 0).
+   The source file is specified with a struct symtab.  */
+
+int
+find_line_pc (struct symtab *symtab, int line, CORE_ADDR *pc)
+{
+  struct linetable *l;
+  int ind;
+
+  *pc = 0;
+  if (symtab == 0)
+    return 0;
+
+  symtab = find_line_symtab (symtab, line, &ind, NULL);
+  if (symtab != NULL)
+    {
+      l = LINETABLE (symtab);
+      *pc = l->item[ind].pc;
+      return 1;
+    }
+  else
+    return 0;
+}
+
+/* Find the range of pc values in a line.
+   Store the starting pc of the line into *STARTPTR
+   and the ending pc (start of next line) into *ENDPTR.
+   Returns 1 to indicate success.
+   Returns 0 if could not find the specified line.  */
+
+int
+find_line_pc_range (struct symtab_and_line sal, CORE_ADDR *startptr,
+                   CORE_ADDR *endptr)
+{
+  CORE_ADDR startaddr;
+  struct symtab_and_line found_sal;
+
+  startaddr = sal.pc;
+  if (startaddr == 0 && !find_line_pc (sal.symtab, sal.line, &startaddr))
+    return 0;
+
+  /* This whole function is based on address.  For example, if line 10 has
+     two parts, one from 0x100 to 0x200 and one from 0x300 to 0x400, then
+     "info line *0x123" should say the line goes from 0x100 to 0x200
+     and "info line *0x355" should say the line goes from 0x300 to 0x400.
+     This also insures that we never give a range like "starts at 0x134
+     and ends at 0x12c".  */
+
+  found_sal = find_pc_sect_line (startaddr, sal.section, 0);
+  if (found_sal.line != sal.line)
+    {
+      /* The specified line (sal) has zero bytes.  */
+      *startptr = found_sal.pc;
+      *endptr = found_sal.pc;
+    }
+  else
+    {
+      *startptr = found_sal.pc;
+      *endptr = found_sal.end;
+    }
+  return 1;
+}
+
+/* Given a line table and a line number, return the index into the line
+   table for the pc of the nearest line whose number is >= the specified one.
+   Return -1 if none is found.  The value is >= 0 if it is an index.
+
+   Set *EXACT_MATCH nonzero if the value returned is an exact match.  */
+
+static int
+find_line_common (register struct linetable *l, register int lineno,
+                 int *exact_match)
+{
+  register int i;
+  register int len;
+
+  /* BEST is the smallest linenumber > LINENO so far seen,
+     or 0 if none has been seen so far.
+     BEST_INDEX identifies the item for it.  */
+
+  int best_index = -1;
+  int best = 0;
+
+  if (lineno <= 0)
+    return -1;
+  if (l == 0)
+    return -1;
+
+  len = l->nitems;
+  for (i = 0; i < len; i++)
+    {
+      register struct linetable_entry *item = &(l->item[i]);
+
+      if (item->line == lineno)
+       {
+         /* Return the first (lowest address) entry which matches.  */
+         *exact_match = 1;
+         return i;
+       }
+
+      if (item->line > lineno && (best == 0 || item->line < best))
+       {
+         best = item->line;
+         best_index = i;
+       }
+    }
+
+  /* If we got here, we didn't get an exact match.  */
+
+  *exact_match = 0;
+  return best_index;
+}
+
+int
+find_pc_line_pc_range (CORE_ADDR pc, CORE_ADDR *startptr, CORE_ADDR *endptr)
+{
+  struct symtab_and_line sal;
+  sal = find_pc_line (pc, 0);
+  *startptr = sal.pc;
+  *endptr = sal.end;
+  return sal.symtab != 0;
+}
+
+/* Given a function symbol SYM, find the symtab and line for the start
+   of the function.
+   If the argument FUNFIRSTLINE is nonzero, we want the first line
+   of real code inside the function.  */
+
+struct symtab_and_line
+find_function_start_sal (struct symbol *sym, int funfirstline)
+{
+  CORE_ADDR pc;
+  struct symtab_and_line sal;
+
+  pc = BLOCK_START (SYMBOL_BLOCK_VALUE (sym));
+  fixup_symbol_section (sym, NULL);
+  if (funfirstline)
+    {                          /* skip "first line" of function (which is actually its prologue) */
+      asection *section = SYMBOL_BFD_SECTION (sym);
+      /* If function is in an unmapped overlay, use its unmapped LMA
+         address, so that SKIP_PROLOGUE has something unique to work on */
+      if (section_is_overlay (section) &&
+         !section_is_mapped (section))
+       pc = overlay_unmapped_address (pc, section);
+
+      pc += FUNCTION_START_OFFSET;
+      pc = SKIP_PROLOGUE (pc);
+
+      /* For overlays, map pc back into its mapped VMA range */
+      pc = overlay_mapped_address (pc, section);
+    }
+  sal = find_pc_sect_line (pc, SYMBOL_BFD_SECTION (sym), 0);
+
+#ifdef PROLOGUE_FIRSTLINE_OVERLAP
+  /* Convex: no need to suppress code on first line, if any */
+  sal.pc = pc;
+#else
+  /* Check if SKIP_PROLOGUE left us in mid-line, and the next
+     line is still part of the same function.  */
+  if (sal.pc != pc
+      && BLOCK_START (SYMBOL_BLOCK_VALUE (sym)) <= sal.end
+      && sal.end < BLOCK_END (SYMBOL_BLOCK_VALUE (sym)))
+    {
+      /* First pc of next line */
+      pc = sal.end;
+      /* Recalculate the line number (might not be N+1).  */
+      sal = find_pc_sect_line (pc, SYMBOL_BFD_SECTION (sym), 0);
+    }
+  sal.pc = pc;
+#endif
+
+  return sal;
+}
+
+/* If P is of the form "operator[ \t]+..." where `...' is
+   some legitimate operator text, return a pointer to the
+   beginning of the substring of the operator text.
+   Otherwise, return "".  */
+char *
+operator_chars (char *p, char **end)
+{
+  *end = "";
+  if (strncmp (p, "operator", 8))
+    return *end;
+  p += 8;
+
+  /* Don't get faked out by `operator' being part of a longer
+     identifier.  */
+  if (isalpha (*p) || *p == '_' || *p == '$' || *p == '\0')
+    return *end;
+
+  /* Allow some whitespace between `operator' and the operator symbol.  */
+  while (*p == ' ' || *p == '\t')
+    p++;
+
+  /* Recognize 'operator TYPENAME'. */
+
+  if (isalpha (*p) || *p == '_' || *p == '$')
+    {
+      register char *q = p + 1;
+      while (isalnum (*q) || *q == '_' || *q == '$')
+       q++;
+      *end = q;
+      return p;
+    }
+
+  while (*p)
+    switch (*p)
+      {
+      case '\\':                       /* regexp quoting */
+       if (p[1] == '*')
+         {
+           if (p[2] == '=')    /* 'operator\*=' */
+             *end = p + 3;
+           else                        /* 'operator\*'  */
+             *end = p + 2;
+           return p;
+         }
+       else if (p[1] == '[')
+         {
+           if (p[2] == ']')
+             error ("mismatched quoting on brackets, try 'operator\\[\\]'");
+           else if (p[2] == '\\' && p[3] == ']')
+             {
+               *end = p + 4;   /* 'operator\[\]' */
+               return p;
+             }
+           else
+             error ("nothing is allowed between '[' and ']'");
+         }
+       else 
+         {
+           /* Gratuitous qoute: skip it and move on. */
+           p++;
+           continue;
+         }
+       break;
+      case '!':
+      case '=':
+      case '*':
+      case '/':
+      case '%':
+      case '^':
+       if (p[1] == '=')
+         *end = p + 2;
+       else
+         *end = p + 1;
+       return p;
+      case '<':
+      case '>':
+      case '+':
+      case '-':
+      case '&':
+      case '|':
+       if (p[0] == '-' && p[1] == '>')
+         {
+           /* Struct pointer member operator 'operator->'. */
+           if (p[2] == '*')
+             {
+               *end = p + 3;   /* 'operator->*' */
+               return p;
+             }
+           else if (p[2] == '\\')
+             {
+               *end = p + 4;   /* Hopefully 'operator->\*' */
+               return p;
+             }
+           else
+             {
+               *end = p + 2;   /* 'operator->' */
+               return p;
+             }
+         }
+       if (p[1] == '=' || p[1] == p[0])
+         *end = p + 2;
+       else
+         *end = p + 1;
+       return p;
+      case '~':
+      case ',':
+       *end = p + 1;
+       return p;
+      case '(':
+       if (p[1] != ')')
+         error ("`operator ()' must be specified without whitespace in `()'");
+       *end = p + 2;
+       return p;
+      case '?':
+       if (p[1] != ':')
+         error ("`operator ?:' must be specified without whitespace in `?:'");
+       *end = p + 2;
+       return p;
+      case '[':
+       if (p[1] != ']')
+         error ("`operator []' must be specified without whitespace in `[]'");
+       *end = p + 2;
+       return p;
+      default:
+       error ("`operator %s' not supported", p);
+       break;
+      }
+
+  *end = "";
+  return *end;
+}
+\f
+
+/* If FILE is not already in the table of files, return zero;
+   otherwise return non-zero.  Optionally add FILE to the table if ADD
+   is non-zero.  If *FIRST is non-zero, forget the old table
+   contents.  */
+static int
+filename_seen (const char *file, int add, int *first)
+{
+  /* Table of files seen so far.  */
+  static const char **tab = NULL;
+  /* Allocated size of tab in elements.
+     Start with one 256-byte block (when using GNU malloc.c).
+     24 is the malloc overhead when range checking is in effect.  */
+  static int tab_alloc_size = (256 - 24) / sizeof (char *);
+  /* Current size of tab in elements.  */
+  static int tab_cur_size;
+  const char **p;
+
+  if (*first)
+    {
+      if (tab == NULL)
+       tab = (const char **) xmalloc (tab_alloc_size * sizeof (*tab));
+      tab_cur_size = 0;
+    }
+
+  /* Is FILE in tab?  */
+  for (p = tab; p < tab + tab_cur_size; p++)
+    if (strcmp (*p, file) == 0)
+      return 1;
+
+  /* No; maybe add it to tab.  */
+  if (add)
+    {
+      if (tab_cur_size == tab_alloc_size)
+       {
+         tab_alloc_size *= 2;
+         tab = (const char **) xrealloc ((char *) tab,
+                                         tab_alloc_size * sizeof (*tab));
+       }
+      tab[tab_cur_size++] = file;
+    }
+
+  return 0;
+}
+
+/* Slave routine for sources_info.  Force line breaks at ,'s.
+   NAME is the name to print and *FIRST is nonzero if this is the first
+   name printed.  Set *FIRST to zero.  */
+static void
+output_source_filename (char *name, int *first)
+{
+  /* Since a single source file can result in several partial symbol
+     tables, we need to avoid printing it more than once.  Note: if
+     some of the psymtabs are read in and some are not, it gets
+     printed both under "Source files for which symbols have been
+     read" and "Source files for which symbols will be read in on
+     demand".  I consider this a reasonable way to deal with the
+     situation.  I'm not sure whether this can also happen for
+     symtabs; it doesn't hurt to check.  */
+
+  /* Was NAME already seen?  */
+  if (filename_seen (name, 1, first))
+    {
+      /* Yes; don't print it again.  */
+      return;
+    }
+  /* No; print it and reset *FIRST.  */
+  if (*first)
+    {
+      *first = 0;
+    }
+  else
+    {
+      printf_filtered (", ");
+    }
+
+  wrap_here ("");
+  fputs_filtered (name, gdb_stdout);
+}
+
+static void
+sources_info (char *ignore, int from_tty)
+{
+  register struct symtab *s;
+  register struct partial_symtab *ps;
+  register struct objfile *objfile;
+  int first;
+
+  if (!have_full_symbols () && !have_partial_symbols ())
+    {
+      error ("No symbol table is loaded.  Use the \"file\" command.");
+    }
+
+  printf_filtered ("Source files for which symbols have been read in:\n\n");
+
+  first = 1;
+  ALL_SYMTABS (objfile, s)
+  {
+    output_source_filename (s->filename, &first);
+  }
+  printf_filtered ("\n\n");
+
+  printf_filtered ("Source files for which symbols will be read in on demand:\n\n");
+
+  first = 1;
+  ALL_PSYMTABS (objfile, ps)
+  {
+    if (!ps->readin)
+      {
+       output_source_filename (ps->filename, &first);
+      }
+  }
+  printf_filtered ("\n");
+}
+
+static int
+file_matches (char *file, char *files[], int nfiles)
+{
+  int i;
+
+  if (file != NULL && nfiles != 0)
+    {
+      for (i = 0; i < nfiles; i++)
+       {
+         if (strcmp (files[i], lbasename (file)) == 0)
+           return 1;
+       }
+    }
+  else if (nfiles == 0)
+    return 1;
+  return 0;
+}
+
+/* Free any memory associated with a search. */
+void
+free_search_symbols (struct symbol_search *symbols)
+{
+  struct symbol_search *p;
+  struct symbol_search *next;
+
+  for (p = symbols; p != NULL; p = next)
+    {
+      next = p->next;
+      xfree (p);
+    }
+}
+
+static void
+do_free_search_symbols_cleanup (void *symbols)
+{
+  free_search_symbols (symbols);
+}
+
+struct cleanup *
+make_cleanup_free_search_symbols (struct symbol_search *symbols)
+{
+  return make_cleanup (do_free_search_symbols_cleanup, symbols);
+}
+
+/* Helper function for sort_search_symbols and qsort.  Can only
+   sort symbols, not minimal symbols.  */
+static int
+compare_search_syms (const void *sa, const void *sb)
+{
+  struct symbol_search **sym_a = (struct symbol_search **) sa;
+  struct symbol_search **sym_b = (struct symbol_search **) sb;
+
+  return strcmp (SYMBOL_SOURCE_NAME ((*sym_a)->symbol),
+                SYMBOL_SOURCE_NAME ((*sym_b)->symbol));
+}
+
+/* Sort the ``nfound'' symbols in the list after prevtail.  Leave
+   prevtail where it is, but update its next pointer to point to
+   the first of the sorted symbols.  */
+static struct symbol_search *
+sort_search_symbols (struct symbol_search *prevtail, int nfound)
+{
+  struct symbol_search **symbols, *symp, *old_next;
+  int i;
+
+  symbols = (struct symbol_search **) xmalloc (sizeof (struct symbol_search *)
+                                              * nfound);
+  symp = prevtail->next;
+  for (i = 0; i < nfound; i++)
+    {
+      symbols[i] = symp;
+      symp = symp->next;
+    }
+  /* Generally NULL.  */
+  old_next = symp;
+
+  qsort (symbols, nfound, sizeof (struct symbol_search *),
+        compare_search_syms);
+
+  symp = prevtail;
+  for (i = 0; i < nfound; i++)
+    {
+      symp->next = symbols[i];
+      symp = symp->next;
+    }
+  symp->next = old_next;
+
+  xfree (symbols);
+  return symp;
+}
+
+/* Search the symbol table for matches to the regular expression REGEXP,
+   returning the results in *MATCHES.
+
+   Only symbols of KIND are searched:
+   FUNCTIONS_NAMESPACE - search all functions
+   TYPES_NAMESPACE     - search all type names
+   METHODS_NAMESPACE   - search all methods NOT IMPLEMENTED
+   VARIABLES_NAMESPACE - search all symbols, excluding functions, type names,
+   and constants (enums)
+
+   free_search_symbols should be called when *MATCHES is no longer needed.
+
+   The results are sorted locally; each symtab's global and static blocks are
+   separately alphabetized.
+ */
+void
+search_symbols (char *regexp, namespace_enum kind, int nfiles, char *files[],
+               struct symbol_search **matches)
+{
+  register struct symtab *s;
+  register struct partial_symtab *ps;
+  register struct blockvector *bv;
+  struct blockvector *prev_bv = 0;
+  register struct block *b;
+  register int i = 0;
+  register int j;
+  register struct symbol *sym;
+  struct partial_symbol **psym;
+  struct objfile *objfile;
+  struct minimal_symbol *msymbol;
+  char *val;
+  int found_misc = 0;
+  static enum minimal_symbol_type types[]
+  =
+  {mst_data, mst_text, mst_abs, mst_unknown};
+  static enum minimal_symbol_type types2[]
+  =
+  {mst_bss, mst_file_text, mst_abs, mst_unknown};
+  static enum minimal_symbol_type types3[]
+  =
+  {mst_file_data, mst_solib_trampoline, mst_abs, mst_unknown};
+  static enum minimal_symbol_type types4[]
+  =
+  {mst_file_bss, mst_text, mst_abs, mst_unknown};
+  enum minimal_symbol_type ourtype;
+  enum minimal_symbol_type ourtype2;
+  enum minimal_symbol_type ourtype3;
+  enum minimal_symbol_type ourtype4;
+  struct symbol_search *sr;
+  struct symbol_search *psr;
+  struct symbol_search *tail;
+  struct cleanup *old_chain = NULL;
+
+  if (kind < VARIABLES_NAMESPACE)
+    error ("must search on specific namespace");
+
+  ourtype = types[(int) (kind - VARIABLES_NAMESPACE)];
+  ourtype2 = types2[(int) (kind - VARIABLES_NAMESPACE)];
+  ourtype3 = types3[(int) (kind - VARIABLES_NAMESPACE)];
+  ourtype4 = types4[(int) (kind - VARIABLES_NAMESPACE)];
+
+  sr = *matches = NULL;
+  tail = NULL;
+
+  if (regexp != NULL)
+    {
+      /* Make sure spacing is right for C++ operators.
+         This is just a courtesy to make the matching less sensitive
+         to how many spaces the user leaves between 'operator'
+         and <TYPENAME> or <OPERATOR>. */
+      char *opend;
+      char *opname = operator_chars (regexp, &opend);
+      if (*opname)
+       {
+         int fix = -1;         /* -1 means ok; otherwise number of spaces needed. */
+         if (isalpha (*opname) || *opname == '_' || *opname == '$')
+           {
+             /* There should 1 space between 'operator' and 'TYPENAME'. */
+             if (opname[-1] != ' ' || opname[-2] == ' ')
+               fix = 1;
+           }
+         else
+           {
+             /* There should 0 spaces between 'operator' and 'OPERATOR'. */
+             if (opname[-1] == ' ')
+               fix = 0;
+           }
+         /* If wrong number of spaces, fix it. */
+         if (fix >= 0)
+           {
+             char *tmp = (char *) alloca (8 + fix + strlen (opname) + 1);
+             sprintf (tmp, "operator%.*s%s", fix, " ", opname);
+             regexp = tmp;
+           }
+       }
+
+      if (0 != (val = re_comp (regexp)))
+       error ("Invalid regexp (%s): %s", val, regexp);
+    }
+
+  /* Search through the partial symtabs *first* for all symbols
+     matching the regexp.  That way we don't have to reproduce all of
+     the machinery below. */
+
+  ALL_PSYMTABS (objfile, ps)
+  {
+    struct partial_symbol **bound, **gbound, **sbound;
+    int keep_going = 1;
+
+    if (ps->readin)
+      continue;
+
+    gbound = objfile->global_psymbols.list + ps->globals_offset + ps->n_global_syms;
+    sbound = objfile->static_psymbols.list + ps->statics_offset + ps->n_static_syms;
+    bound = gbound;
+
+    /* Go through all of the symbols stored in a partial
+       symtab in one loop. */
+    psym = objfile->global_psymbols.list + ps->globals_offset;
+    while (keep_going)
+      {
+       if (psym >= bound)
+         {
+           if (bound == gbound && ps->n_static_syms != 0)
+             {
+               psym = objfile->static_psymbols.list + ps->statics_offset;
+               bound = sbound;
+             }
+           else
+             keep_going = 0;
+           continue;
+         }
+       else
+         {
+           QUIT;
+
+           /* If it would match (logic taken from loop below)
+              load the file and go on to the next one */
+           if (file_matches (ps->filename, files, nfiles)
+               && ((regexp == NULL || SYMBOL_MATCHES_REGEXP (*psym))
+                   && ((kind == VARIABLES_NAMESPACE && SYMBOL_CLASS (*psym) != LOC_TYPEDEF
+                        && SYMBOL_CLASS (*psym) != LOC_BLOCK)
+                       || (kind == FUNCTIONS_NAMESPACE && SYMBOL_CLASS (*psym) == LOC_BLOCK)
+                       || (kind == TYPES_NAMESPACE && SYMBOL_CLASS (*psym) == LOC_TYPEDEF)
+                       || (kind == METHODS_NAMESPACE && SYMBOL_CLASS (*psym) == LOC_BLOCK))))
+             {
+               PSYMTAB_TO_SYMTAB (ps);
+               keep_going = 0;
+             }
+         }
+       psym++;
+      }
+  }
+
+  /* Here, we search through the minimal symbol tables for functions
+     and variables that match, and force their symbols to be read.
+     This is in particular necessary for demangled variable names,
+     which are no longer put into the partial symbol tables.
+     The symbol will then be found during the scan of symtabs below.
+
+     For functions, find_pc_symtab should succeed if we have debug info
+     for the function, for variables we have to call lookup_symbol
+     to determine if the variable has debug info.
+     If the lookup fails, set found_misc so that we will rescan to print
+     any matching symbols without debug info.
+   */
+
+  if (nfiles == 0 && (kind == VARIABLES_NAMESPACE || kind == FUNCTIONS_NAMESPACE))
+    {
+      ALL_MSYMBOLS (objfile, msymbol)
+      {
+       if (MSYMBOL_TYPE (msymbol) == ourtype ||
+           MSYMBOL_TYPE (msymbol) == ourtype2 ||
+           MSYMBOL_TYPE (msymbol) == ourtype3 ||
+           MSYMBOL_TYPE (msymbol) == ourtype4)
+         {
+           if (regexp == NULL || SYMBOL_MATCHES_REGEXP (msymbol))
+             {
+               if (0 == find_pc_symtab (SYMBOL_VALUE_ADDRESS (msymbol)))
+                 {
+                   if (kind == FUNCTIONS_NAMESPACE
+                       || lookup_symbol (SYMBOL_NAME (msymbol),
+                                         (struct block *) NULL,
+                                         VAR_NAMESPACE,
+                                       0, (struct symtab **) NULL) == NULL)
+                     found_misc = 1;
+                 }
+             }
+         }
+      }
+    }
+
+  ALL_SYMTABS (objfile, s)
+  {
+    bv = BLOCKVECTOR (s);
+    /* Often many files share a blockvector.
+       Scan each blockvector only once so that
+       we don't get every symbol many times.
+       It happens that the first symtab in the list
+       for any given blockvector is the main file.  */
+    if (bv != prev_bv)
+      for (i = GLOBAL_BLOCK; i <= STATIC_BLOCK; i++)
+       {
+         struct symbol_search *prevtail = tail;
+         int nfound = 0;
+         b = BLOCKVECTOR_BLOCK (bv, i);
+         ALL_BLOCK_SYMBOLS (b, j, sym)
+           {
+             QUIT;
+             if (file_matches (s->filename, files, nfiles)
+                 && ((regexp == NULL || SYMBOL_MATCHES_REGEXP (sym))
+                     && ((kind == VARIABLES_NAMESPACE && SYMBOL_CLASS (sym) != LOC_TYPEDEF
+                          && SYMBOL_CLASS (sym) != LOC_BLOCK
+                          && SYMBOL_CLASS (sym) != LOC_CONST)
+                         || (kind == FUNCTIONS_NAMESPACE && SYMBOL_CLASS (sym) == LOC_BLOCK)
+                         || (kind == TYPES_NAMESPACE && SYMBOL_CLASS (sym) == LOC_TYPEDEF)
+                         || (kind == METHODS_NAMESPACE && SYMBOL_CLASS (sym) == LOC_BLOCK))))
+               {
+                 /* match */
+                 psr = (struct symbol_search *) xmalloc (sizeof (struct symbol_search));
+                 psr->block = i;
+                 psr->symtab = s;
+                 psr->symbol = sym;
+                 psr->msymbol = NULL;
+                 psr->next = NULL;
+                 if (tail == NULL)
+                   sr = psr;
+                 else
+                   tail->next = psr;
+                 tail = psr;
+                 nfound ++;
+               }
+           }
+         if (nfound > 0)
+           {
+             if (prevtail == NULL)
+               {
+                 struct symbol_search dummy;
+
+                 dummy.next = sr;
+                 tail = sort_search_symbols (&dummy, nfound);
+                 sr = dummy.next;
+
+                 old_chain = make_cleanup_free_search_symbols (sr);
+               }
+             else
+               tail = sort_search_symbols (prevtail, nfound);
+           }
+       }
+    prev_bv = bv;
+  }
+
+  /* If there are no eyes, avoid all contact.  I mean, if there are
+     no debug symbols, then print directly from the msymbol_vector.  */
+
+  if (found_misc || kind != FUNCTIONS_NAMESPACE)
+    {
+      ALL_MSYMBOLS (objfile, msymbol)
+      {
+       if (MSYMBOL_TYPE (msymbol) == ourtype ||
+           MSYMBOL_TYPE (msymbol) == ourtype2 ||
+           MSYMBOL_TYPE (msymbol) == ourtype3 ||
+           MSYMBOL_TYPE (msymbol) == ourtype4)
+         {
+           if (regexp == NULL || SYMBOL_MATCHES_REGEXP (msymbol))
+             {
+               /* Functions:  Look up by address. */
+               if (kind != FUNCTIONS_NAMESPACE ||
+                   (0 == find_pc_symtab (SYMBOL_VALUE_ADDRESS (msymbol))))
+                 {
+                   /* Variables/Absolutes:  Look up by name */
+                   if (lookup_symbol (SYMBOL_NAME (msymbol),
+                                      (struct block *) NULL, VAR_NAMESPACE,
+                                      0, (struct symtab **) NULL) == NULL)
+                     {
+                       /* match */
+                       psr = (struct symbol_search *) xmalloc (sizeof (struct symbol_search));
+                       psr->block = i;
+                       psr->msymbol = msymbol;
+                       psr->symtab = NULL;
+                       psr->symbol = NULL;
+                       psr->next = NULL;
+                       if (tail == NULL)
+                         {
+                           sr = psr;
+                           old_chain = make_cleanup_free_search_symbols (sr);
+                         }
+                       else
+                         tail->next = psr;
+                       tail = psr;
+                     }
+                 }
+             }
+         }
+      }
+    }
+
+  *matches = sr;
+  if (sr != NULL)
+    discard_cleanups (old_chain);
+}
+
+/* Helper function for symtab_symbol_info, this function uses
+   the data returned from search_symbols() to print information
+   regarding the match to gdb_stdout.
+ */
+static void
+print_symbol_info (namespace_enum kind, struct symtab *s, struct symbol *sym,
+                  int block, char *last)
+{
+  if (last == NULL || strcmp (last, s->filename) != 0)
+    {
+      fputs_filtered ("\nFile ", gdb_stdout);
+      fputs_filtered (s->filename, gdb_stdout);
+      fputs_filtered (":\n", gdb_stdout);
+    }
+
+  if (kind != TYPES_NAMESPACE && block == STATIC_BLOCK)
+    printf_filtered ("static ");
+
+  /* Typedef that is not a C++ class */
+  if (kind == TYPES_NAMESPACE
+      && SYMBOL_NAMESPACE (sym) != STRUCT_NAMESPACE)
+    typedef_print (SYMBOL_TYPE (sym), sym, gdb_stdout);
+  /* variable, func, or typedef-that-is-c++-class */
+  else if (kind < TYPES_NAMESPACE ||
+          (kind == TYPES_NAMESPACE &&
+           SYMBOL_NAMESPACE (sym) == STRUCT_NAMESPACE))
+    {
+      type_print (SYMBOL_TYPE (sym),
+                 (SYMBOL_CLASS (sym) == LOC_TYPEDEF
+                  ? "" : SYMBOL_SOURCE_NAME (sym)),
+                 gdb_stdout, 0);
+
+      printf_filtered (";\n");
+    }
+  else
+    {
+#if 0
+      /* Tiemann says: "info methods was never implemented."  */
+      char *demangled_name;
+      c_type_print_base (TYPE_FN_FIELD_TYPE (t, block),
+                        gdb_stdout, 0, 0);
+      c_type_print_varspec_prefix (TYPE_FN_FIELD_TYPE (t, block),
+                                  gdb_stdout, 0);
+      if (TYPE_FN_FIELD_STUB (t, block))
+       check_stub_method (TYPE_DOMAIN_TYPE (type), j, block);
+      demangled_name =
+       cplus_demangle (TYPE_FN_FIELD_PHYSNAME (t, block),
+                       DMGL_ANSI | DMGL_PARAMS);
+      if (demangled_name == NULL)
+       fprintf_filtered (stream, "<badly mangled name %s>",
+                         TYPE_FN_FIELD_PHYSNAME (t, block));
+      else
+       {
+         fputs_filtered (demangled_name, stream);
+         xfree (demangled_name);
+       }
+#endif
+    }
+}
+
+/* This help function for symtab_symbol_info() prints information
+   for non-debugging symbols to gdb_stdout.
+ */
+static void
+print_msymbol_info (struct minimal_symbol *msymbol)
+{
+  char *tmp;
+
+  if (TARGET_ADDR_BIT <= 32)
+    tmp = local_hex_string_custom (SYMBOL_VALUE_ADDRESS (msymbol)
+                                  & (CORE_ADDR) 0xffffffff,
+                                  "08l");
+  else
+    tmp = local_hex_string_custom (SYMBOL_VALUE_ADDRESS (msymbol),
+                                  "016l");
+  printf_filtered ("%s  %s\n",
+                  tmp, SYMBOL_SOURCE_NAME (msymbol));
+}
+
+/* This is the guts of the commands "info functions", "info types", and
+   "info variables". It calls search_symbols to find all matches and then
+   print_[m]symbol_info to print out some useful information about the
+   matches.
+ */
+static void
+symtab_symbol_info (char *regexp, namespace_enum kind, int from_tty)
+{
+  static char *classnames[]
+  =
+  {"variable", "function", "type", "method"};
+  struct symbol_search *symbols;
+  struct symbol_search *p;
+  struct cleanup *old_chain;
+  char *last_filename = NULL;
+  int first = 1;
+
+  /* must make sure that if we're interrupted, symbols gets freed */
+  search_symbols (regexp, kind, 0, (char **) NULL, &symbols);
+  old_chain = make_cleanup_free_search_symbols (symbols);
+
+  printf_filtered (regexp
+                  ? "All %ss matching regular expression \"%s\":\n"
+                  : "All defined %ss:\n",
+                  classnames[(int) (kind - VARIABLES_NAMESPACE)], regexp);
+
+  for (p = symbols; p != NULL; p = p->next)
+    {
+      QUIT;
+
+      if (p->msymbol != NULL)
+       {
+         if (first)
+           {
+             printf_filtered ("\nNon-debugging symbols:\n");
+             first = 0;
+           }
+         print_msymbol_info (p->msymbol);
+       }
+      else
+       {
+         print_symbol_info (kind,
+                            p->symtab,
+                            p->symbol,
+                            p->block,
+                            last_filename);
+         last_filename = p->symtab->filename;
+       }
+    }
+
+  do_cleanups (old_chain);
+}
+
+static void
+variables_info (char *regexp, int from_tty)
+{
+  symtab_symbol_info (regexp, VARIABLES_NAMESPACE, from_tty);
+}
+
+static void
+functions_info (char *regexp, int from_tty)
+{
+  symtab_symbol_info (regexp, FUNCTIONS_NAMESPACE, from_tty);
+}
+
+
+static void
+types_info (char *regexp, int from_tty)
+{
+  symtab_symbol_info (regexp, TYPES_NAMESPACE, from_tty);
+}
+
+#if 0
+/* Tiemann says: "info methods was never implemented."  */
+static void
+methods_info (char *regexp)
+{
+  symtab_symbol_info (regexp, METHODS_NAMESPACE, 0, from_tty);
+}
+#endif /* 0 */
+
+/* Breakpoint all functions matching regular expression. */
+
+void
+rbreak_command_wrapper (char *regexp, int from_tty)
+{
+  rbreak_command (regexp, from_tty);
+}
+
+static void
+rbreak_command (char *regexp, int from_tty)
+{
+  struct symbol_search *ss;
+  struct symbol_search *p;
+  struct cleanup *old_chain;
+
+  search_symbols (regexp, FUNCTIONS_NAMESPACE, 0, (char **) NULL, &ss);
+  old_chain = make_cleanup_free_search_symbols (ss);
+
+  for (p = ss; p != NULL; p = p->next)
+    {
+      if (p->msymbol == NULL)
+       {
+         char *string = (char *) alloca (strlen (p->symtab->filename)
+                                         + strlen (SYMBOL_NAME (p->symbol))
+                                         + 4);
+         strcpy (string, p->symtab->filename);
+         strcat (string, ":'");
+         strcat (string, SYMBOL_NAME (p->symbol));
+         strcat (string, "'");
+         break_command (string, from_tty);
+         print_symbol_info (FUNCTIONS_NAMESPACE,
+                            p->symtab,
+                            p->symbol,
+                            p->block,
+                            p->symtab->filename);
+       }
+      else
+       {
+         break_command (SYMBOL_NAME (p->msymbol), from_tty);
+         printf_filtered ("<function, no debug info> %s;\n",
+                          SYMBOL_SOURCE_NAME (p->msymbol));
+       }
+    }
+
+  do_cleanups (old_chain);
+}
+\f
+
+/* Return Nonzero if block a is lexically nested within block b,
+   or if a and b have the same pc range.
+   Return zero otherwise. */
+int
+contained_in (struct block *a, struct block *b)
+{
+  if (!a || !b)
+    return 0;
+  return BLOCK_START (a) >= BLOCK_START (b)
+    && BLOCK_END (a) <= BLOCK_END (b);
+}
+\f
+
+/* Helper routine for make_symbol_completion_list.  */
+
+static int return_val_size;
+static int return_val_index;
+static char **return_val;
+
+#define COMPLETION_LIST_ADD_SYMBOL(symbol, sym_text, len, text, word) \
+  do { \
+    if (SYMBOL_DEMANGLED_NAME (symbol) != NULL) \
+      /* Put only the mangled name on the list.  */ \
+      /* Advantage:  "b foo<TAB>" completes to "b foo(int, int)" */ \
+      /* Disadvantage:  "b foo__i<TAB>" doesn't complete.  */ \
+      completion_list_add_name \
+       (SYMBOL_DEMANGLED_NAME (symbol), (sym_text), (len), (text), (word)); \
+    else \
+      completion_list_add_name \
+       (SYMBOL_NAME (symbol), (sym_text), (len), (text), (word)); \
+  } while (0)
+
+/*  Test to see if the symbol specified by SYMNAME (which is already
+   demangled for C++ symbols) matches SYM_TEXT in the first SYM_TEXT_LEN
+   characters.  If so, add it to the current completion list. */
+
+static void
+completion_list_add_name (char *symname, char *sym_text, int sym_text_len,
+                         char *text, char *word)
+{
+  int newsize;
+  int i;
+
+  /* clip symbols that cannot match */
+
+  if (strncmp (symname, sym_text, sym_text_len) != 0)
+    {
+      return;
+    }
+
+  /* We have a match for a completion, so add SYMNAME to the current list
+     of matches. Note that the name is moved to freshly malloc'd space. */
+
+  {
+    char *new;
+    if (word == sym_text)
+      {
+       new = xmalloc (strlen (symname) + 5);
+       strcpy (new, symname);
+      }
+    else if (word > sym_text)
+      {
+       /* Return some portion of symname.  */
+       new = xmalloc (strlen (symname) + 5);
+       strcpy (new, symname + (word - sym_text));
+      }
+    else
+      {
+       /* Return some of SYM_TEXT plus symname.  */
+       new = xmalloc (strlen (symname) + (sym_text - word) + 5);
+       strncpy (new, word, sym_text - word);
+       new[sym_text - word] = '\0';
+       strcat (new, symname);
+      }
+
+    if (return_val_index + 3 > return_val_size)
+      {
+       newsize = (return_val_size *= 2) * sizeof (char *);
+       return_val = (char **) xrealloc ((char *) return_val, newsize);
+      }
+    return_val[return_val_index++] = new;
+    return_val[return_val_index] = NULL;
+  }
+}
+
+/* Return a NULL terminated array of all symbols (regardless of class)
+   which begin by matching TEXT.  If the answer is no symbols, then
+   the return value is an array which contains only a NULL pointer.
+
+   Problem: All of the symbols have to be copied because readline frees them.
+   I'm not going to worry about this; hopefully there won't be that many.  */
+
+char **
+make_symbol_completion_list (char *text, char *word)
+{
+  register struct symbol *sym;
+  register struct symtab *s;
+  register struct partial_symtab *ps;
+  register struct minimal_symbol *msymbol;
+  register struct objfile *objfile;
+  register struct block *b, *surrounding_static_block = 0;
+  register int i, j;
+  struct partial_symbol **psym;
+  /* The symbol we are completing on.  Points in same buffer as text.  */
+  char *sym_text;
+  /* Length of sym_text.  */
+  int sym_text_len;
+
+  /* Now look for the symbol we are supposed to complete on.
+     FIXME: This should be language-specific.  */
+  {
+    char *p;
+    char quote_found;
+    char *quote_pos = NULL;
+
+    /* First see if this is a quoted string.  */
+    quote_found = '\0';
+    for (p = text; *p != '\0'; ++p)
+      {
+       if (quote_found != '\0')
+         {
+           if (*p == quote_found)
+             /* Found close quote.  */
+             quote_found = '\0';
+           else if (*p == '\\' && p[1] == quote_found)
+             /* A backslash followed by the quote character
+                doesn't end the string.  */
+             ++p;
+         }
+       else if (*p == '\'' || *p == '"')
+         {
+           quote_found = *p;
+           quote_pos = p;
+         }
+      }
+    if (quote_found == '\'')
+      /* A string within single quotes can be a symbol, so complete on it.  */
+      sym_text = quote_pos + 1;
+    else if (quote_found == '"')
+      /* A double-quoted string is never a symbol, nor does it make sense
+         to complete it any other way.  */
+      {
+       return_val = (char **) xmalloc (sizeof (char *));
+       return_val[0] = NULL;
+       return return_val;
+      }
+    else
+      {
+       /* It is not a quoted string.  Break it based on the characters
+          which are in symbols.  */
+       while (p > text)
+         {
+           if (isalnum (p[-1]) || p[-1] == '_' || p[-1] == '\0')
+             --p;
+           else
+             break;
+         }
+       sym_text = p;
+      }
+  }
+
+  sym_text_len = strlen (sym_text);
+
+  return_val_size = 100;
+  return_val_index = 0;
+  return_val = (char **) xmalloc ((return_val_size + 1) * sizeof (char *));
+  return_val[0] = NULL;
+
+  /* Look through the partial symtabs for all symbols which begin
+     by matching SYM_TEXT.  Add each one that you find to the list.  */
+
+  ALL_PSYMTABS (objfile, ps)
+  {
+    /* If the psymtab's been read in we'll get it when we search
+       through the blockvector.  */
+    if (ps->readin)
+      continue;
+
+    for (psym = objfile->global_psymbols.list + ps->globals_offset;
+        psym < (objfile->global_psymbols.list + ps->globals_offset
+                + ps->n_global_syms);
+        psym++)
+      {
+       /* If interrupted, then quit. */
+       QUIT;
+       COMPLETION_LIST_ADD_SYMBOL (*psym, sym_text, sym_text_len, text, word);
+      }
+
+    for (psym = objfile->static_psymbols.list + ps->statics_offset;
+        psym < (objfile->static_psymbols.list + ps->statics_offset
+                + ps->n_static_syms);
+        psym++)
+      {
+       QUIT;
+       COMPLETION_LIST_ADD_SYMBOL (*psym, sym_text, sym_text_len, text, word);
+      }
+  }
+
+  /* At this point scan through the misc symbol vectors and add each
+     symbol you find to the list.  Eventually we want to ignore
+     anything that isn't a text symbol (everything else will be
+     handled by the psymtab code above).  */
+
+  ALL_MSYMBOLS (objfile, msymbol)
+  {
+    QUIT;
+    COMPLETION_LIST_ADD_SYMBOL (msymbol, sym_text, sym_text_len, text, word);
+  }
+
+  /* Search upwards from currently selected frame (so that we can
+     complete on local vars.  */
+
+  for (b = get_selected_block (0); b != NULL; b = BLOCK_SUPERBLOCK (b))
+    {
+      if (!BLOCK_SUPERBLOCK (b))
+       {
+         surrounding_static_block = b;         /* For elmin of dups */
+       }
+
+      /* Also catch fields of types defined in this places which match our
+         text string.  Only complete on types visible from current context. */
+
+      ALL_BLOCK_SYMBOLS (b, i, sym)
+       {
+         COMPLETION_LIST_ADD_SYMBOL (sym, sym_text, sym_text_len, text, word);
+         if (SYMBOL_CLASS (sym) == LOC_TYPEDEF)
+           {
+             struct type *t = SYMBOL_TYPE (sym);
+             enum type_code c = TYPE_CODE (t);
+
+             if (c == TYPE_CODE_UNION || c == TYPE_CODE_STRUCT)
+               {
+                 for (j = TYPE_N_BASECLASSES (t); j < TYPE_NFIELDS (t); j++)
+                   {
+                     if (TYPE_FIELD_NAME (t, j))
+                       {
+                         completion_list_add_name (TYPE_FIELD_NAME (t, j),
+                                       sym_text, sym_text_len, text, word);
+                       }
+                   }
+               }
+           }
+       }
+    }
+
+  /* Go through the symtabs and check the externs and statics for
+     symbols which match.  */
+
+  ALL_SYMTABS (objfile, s)
+  {
+    QUIT;
+    b = BLOCKVECTOR_BLOCK (BLOCKVECTOR (s), GLOBAL_BLOCK);
+    ALL_BLOCK_SYMBOLS (b, i, sym)
+      {
+       COMPLETION_LIST_ADD_SYMBOL (sym, sym_text, sym_text_len, text, word);
+      }
+  }
+
+  ALL_SYMTABS (objfile, s)
+  {
+    QUIT;
+    b = BLOCKVECTOR_BLOCK (BLOCKVECTOR (s), STATIC_BLOCK);
+    /* Don't do this block twice.  */
+    if (b == surrounding_static_block)
+      continue;
+    ALL_BLOCK_SYMBOLS (b, i, sym)
+      {
+       COMPLETION_LIST_ADD_SYMBOL (sym, sym_text, sym_text_len, text, word);
+      }
+  }
+
+  return (return_val);
+}
+
+/* Like make_symbol_completion_list, but returns a list of symbols
+   defined in a source file FILE.  */
+
+char **
+make_file_symbol_completion_list (char *text, char *word, char *srcfile)
+{
+  register struct symbol *sym;
+  register struct symtab *s;
+  register struct block *b;
+  register int i;
+  /* The symbol we are completing on.  Points in same buffer as text.  */
+  char *sym_text;
+  /* Length of sym_text.  */
+  int sym_text_len;
+
+  /* Now look for the symbol we are supposed to complete on.
+     FIXME: This should be language-specific.  */
+  {
+    char *p;
+    char quote_found;
+    char *quote_pos = NULL;
+
+    /* First see if this is a quoted string.  */
+    quote_found = '\0';
+    for (p = text; *p != '\0'; ++p)
+      {
+       if (quote_found != '\0')
+         {
+           if (*p == quote_found)
+             /* Found close quote.  */
+             quote_found = '\0';
+           else if (*p == '\\' && p[1] == quote_found)
+             /* A backslash followed by the quote character
+                doesn't end the string.  */
+             ++p;
+         }
+       else if (*p == '\'' || *p == '"')
+         {
+           quote_found = *p;
+           quote_pos = p;
+         }
+      }
+    if (quote_found == '\'')
+      /* A string within single quotes can be a symbol, so complete on it.  */
+      sym_text = quote_pos + 1;
+    else if (quote_found == '"')
+      /* A double-quoted string is never a symbol, nor does it make sense
+         to complete it any other way.  */
+      {
+       return_val = (char **) xmalloc (sizeof (char *));
+       return_val[0] = NULL;
+       return return_val;
+      }
+    else
+      {
+       /* It is not a quoted string.  Break it based on the characters
+          which are in symbols.  */
+       while (p > text)
+         {
+           if (isalnum (p[-1]) || p[-1] == '_' || p[-1] == '\0')
+             --p;
+           else
+             break;
+         }
+       sym_text = p;
+      }
+  }
+
+  sym_text_len = strlen (sym_text);
+
+  return_val_size = 10;
+  return_val_index = 0;
+  return_val = (char **) xmalloc ((return_val_size + 1) * sizeof (char *));
+  return_val[0] = NULL;
+
+  /* Find the symtab for SRCFILE (this loads it if it was not yet read
+     in).  */
+  s = lookup_symtab (srcfile);
+  if (s == NULL)
+    {
+      /* Maybe they typed the file with leading directories, while the
+        symbol tables record only its basename.  */
+      const char *tail = lbasename (srcfile);
+
+      if (tail > srcfile)
+       s = lookup_symtab (tail);
+    }
+
+  /* If we have no symtab for that file, return an empty list.  */
+  if (s == NULL)
+    return (return_val);
+
+  /* Go through this symtab and check the externs and statics for
+     symbols which match.  */
+
+  b = BLOCKVECTOR_BLOCK (BLOCKVECTOR (s), GLOBAL_BLOCK);
+  ALL_BLOCK_SYMBOLS (b, i, sym)
+    {
+      COMPLETION_LIST_ADD_SYMBOL (sym, sym_text, sym_text_len, text, word);
+    }
+
+  b = BLOCKVECTOR_BLOCK (BLOCKVECTOR (s), STATIC_BLOCK);
+  ALL_BLOCK_SYMBOLS (b, i, sym)
+    {
+      COMPLETION_LIST_ADD_SYMBOL (sym, sym_text, sym_text_len, text, word);
+    }
+
+  return (return_val);
+}
+
+/* A helper function for make_source_files_completion_list.  It adds
+   another file name to a list of possible completions, growing the
+   list as necessary.  */
+
+static void
+add_filename_to_list (const char *fname, char *text, char *word,
+                     char ***list, int *list_used, int *list_alloced)
+{
+  char *new;
+  size_t fnlen = strlen (fname);
+
+  if (*list_used + 1 >= *list_alloced)
+    {
+      *list_alloced *= 2;
+      *list = (char **) xrealloc ((char *) *list,
+                                 *list_alloced * sizeof (char *));
+    }
+
+  if (word == text)
+    {
+      /* Return exactly fname.  */
+      new = xmalloc (fnlen + 5);
+      strcpy (new, fname);
+    }
+  else if (word > text)
+    {
+      /* Return some portion of fname.  */
+      new = xmalloc (fnlen + 5);
+      strcpy (new, fname + (word - text));
+    }
+  else
+    {
+      /* Return some of TEXT plus fname.  */
+      new = xmalloc (fnlen + (text - word) + 5);
+      strncpy (new, word, text - word);
+      new[text - word] = '\0';
+      strcat (new, fname);
+    }
+  (*list)[*list_used] = new;
+  (*list)[++*list_used] = NULL;
+}
+
+static int
+not_interesting_fname (const char *fname)
+{
+  static const char *illegal_aliens[] = {
+    "_globals_",       /* inserted by coff_symtab_read */
+    NULL
+  };
+  int i;
+
+  for (i = 0; illegal_aliens[i]; i++)
+    {
+      if (strcmp (fname, illegal_aliens[i]) == 0)
+       return 1;
+    }
+  return 0;
+}
+
+/* Return a NULL terminated array of all source files whose names
+   begin with matching TEXT.  The file names are looked up in the
+   symbol tables of this program.  If the answer is no matchess, then
+   the return value is an array which contains only a NULL pointer.  */
+
+char **
+make_source_files_completion_list (char *text, char *word)
+{
+  register struct symtab *s;
+  register struct partial_symtab *ps;
+  register struct objfile *objfile;
+  int first = 1;
+  int list_alloced = 1;
+  int list_used = 0;
+  size_t text_len = strlen (text);
+  char **list = (char **) xmalloc (list_alloced * sizeof (char *));
+  const char *base_name;
+
+  list[0] = NULL;
+
+  if (!have_full_symbols () && !have_partial_symbols ())
+    return list;
+
+  ALL_SYMTABS (objfile, s)
+    {
+      if (not_interesting_fname (s->filename))
+       continue;
+      if (!filename_seen (s->filename, 1, &first)
+#if HAVE_DOS_BASED_FILE_SYSTEM
+         && strncasecmp (s->filename, text, text_len) == 0
+#else
+         && strncmp (s->filename, text, text_len) == 0
+#endif
+         )
+       {
+         /* This file matches for a completion; add it to the current
+            list of matches.  */
+         add_filename_to_list (s->filename, text, word,
+                               &list, &list_used, &list_alloced);
+       }
+      else
+       {
+         /* NOTE: We allow the user to type a base name when the
+            debug info records leading directories, but not the other
+            way around.  This is what subroutines of breakpoint
+            command do when they parse file names.  */
+         base_name = lbasename (s->filename);
+         if (base_name != s->filename
+             && !filename_seen (base_name, 1, &first)
+#if HAVE_DOS_BASED_FILE_SYSTEM
+             && strncasecmp (base_name, text, text_len) == 0
+#else
+             && strncmp (base_name, text, text_len) == 0
+#endif
+             )
+           add_filename_to_list (base_name, text, word,
+                                 &list, &list_used, &list_alloced);
+       }
+    }
+
+  ALL_PSYMTABS (objfile, ps)
+    {
+      if (not_interesting_fname (ps->filename))
+       continue;
+      if (!ps->readin)
+       {
+         if (!filename_seen (ps->filename, 1, &first)
+#if HAVE_DOS_BASED_FILE_SYSTEM
+             && strncasecmp (ps->filename, text, text_len) == 0
+#else
+             && strncmp (ps->filename, text, text_len) == 0
+#endif
+             )
+           {
+             /* This file matches for a completion; add it to the
+                current list of matches.  */
+             add_filename_to_list (ps->filename, text, word,
+                                   &list, &list_used, &list_alloced);
+
+           }
+         else
+           {
+             base_name = lbasename (ps->filename);
+             if (base_name != ps->filename
+                 && !filename_seen (base_name, 1, &first)
+#if HAVE_DOS_BASED_FILE_SYSTEM
+                 && strncasecmp (base_name, text, text_len) == 0
+#else
+                 && strncmp (base_name, text, text_len) == 0
+#endif
+                 )
+               add_filename_to_list (base_name, text, word,
+                                     &list, &list_used, &list_alloced);
+           }
+       }
+    }
+
+  return list;
+}
+
+/* Determine if PC is in the prologue of a function.  The prologue is the area
+   between the first instruction of a function, and the first executable line.
+   Returns 1 if PC *might* be in prologue, 0 if definately *not* in prologue.
+
+   If non-zero, func_start is where we think the prologue starts, possibly
+   by previous examination of symbol table information.
+ */
+
+int
+in_prologue (CORE_ADDR pc, CORE_ADDR func_start)
+{
+  struct symtab_and_line sal;
+  CORE_ADDR func_addr, func_end;
+
+  /* We have several sources of information we can consult to figure
+     this out.
+     - Compilers usually emit line number info that marks the prologue
+       as its own "source line".  So the ending address of that "line"
+       is the end of the prologue.  If available, this is the most
+       reliable method.
+     - The minimal symbols and partial symbols, which can usually tell
+       us the starting and ending addresses of a function.
+     - If we know the function's start address, we can call the
+       architecture-defined SKIP_PROLOGUE function to analyze the
+       instruction stream and guess where the prologue ends.
+     - Our `func_start' argument; if non-zero, this is the caller's
+       best guess as to the function's entry point.  At the time of
+       this writing, handle_inferior_event doesn't get this right, so
+       it should be our last resort.  */
+
+  /* Consult the partial symbol table, to find which function
+     the PC is in.  */
+  if (! find_pc_partial_function (pc, NULL, &func_addr, &func_end))
+    {
+      CORE_ADDR prologue_end;
+
+      /* We don't even have minsym information, so fall back to using
+         func_start, if given.  */
+      if (! func_start)
+       return 1;               /* We *might* be in a prologue.  */
+
+      prologue_end = SKIP_PROLOGUE (func_start);
+
+      return func_start <= pc && pc < prologue_end;
+    }
+
+  /* If we have line number information for the function, that's
+     usually pretty reliable.  */
+  sal = find_pc_line (func_addr, 0);
+
+  /* Now sal describes the source line at the function's entry point,
+     which (by convention) is the prologue.  The end of that "line",
+     sal.end, is the end of the prologue.
+
+     Note that, for functions whose source code is all on a single
+     line, the line number information doesn't always end up this way.
+     So we must verify that our purported end-of-prologue address is
+     *within* the function, not at its start or end.  */
+  if (sal.line == 0
+      || sal.end <= func_addr
+      || func_end <= sal.end)
+    {
+      /* We don't have any good line number info, so use the minsym
+        information, together with the architecture-specific prologue
+        scanning code.  */
+      CORE_ADDR prologue_end = SKIP_PROLOGUE (func_addr);
+
+      return func_addr <= pc && pc < prologue_end;
+    }
+
+  /* We have line number info, and it looks good.  */
+  return func_addr <= pc && pc < sal.end;
+}
+
+
+/* Begin overload resolution functions */
+
+static char *
+remove_params (const char *demangled_name)
+{
+  const char *argp;
+  char *new_name;
+  int depth;
+
+  if (demangled_name == NULL)
+    return NULL;
+
+  /* First find the end of the arg list.  */
+  argp = strrchr (demangled_name, ')');
+  if (argp == NULL)
+    return NULL;
+
+  /* Back up to the beginning.  */
+  depth = 1;
+
+  while (argp-- > demangled_name)
+    {
+      if (*argp == ')')
+       depth ++;
+      else if (*argp == '(')
+       {
+         depth --;
+
+         if (depth == 0)
+           break;
+       }
+    }
+  if (depth != 0)
+    internal_error (__FILE__, __LINE__,
+                   "bad demangled name %s\n", demangled_name);
+  while (argp[-1] == ' ' && argp > demangled_name)
+    argp --;
+
+  new_name = xmalloc (argp - demangled_name + 1);
+  memcpy (new_name, demangled_name, argp - demangled_name);
+  new_name[argp - demangled_name] = '\0';
+  return new_name;
+}
+
+/* Helper routine for make_symbol_completion_list.  */
+
+static int sym_return_val_size;
+static int sym_return_val_index;
+static struct symbol **sym_return_val;
+
+/*  Test to see if the symbol specified by SYMNAME (which is already
+   demangled for C++ symbols) matches SYM_TEXT in the first SYM_TEXT_LEN
+   characters.  If so, add it to the current completion list. */
+
+static void
+overload_list_add_symbol (struct symbol *sym, char *oload_name)
+{
+  int newsize;
+  int i;
+  char *sym_name;
+
+  /* If there is no type information, we can't do anything, so skip */
+  if (SYMBOL_TYPE (sym) == NULL)
+    return;
+
+  /* skip any symbols that we've already considered. */
+  for (i = 0; i < sym_return_val_index; ++i)
+    if (!strcmp (SYMBOL_NAME (sym), SYMBOL_NAME (sym_return_val[i])))
+      return;
+
+  /* Get the demangled name without parameters */
+  sym_name = remove_params (SYMBOL_DEMANGLED_NAME (sym));
+  if (!sym_name)
+    return;
+
+  /* skip symbols that cannot match */
+  if (strcmp (sym_name, oload_name) != 0)
+    {
+      xfree (sym_name);
+      return;
+    }
+
+  xfree (sym_name);
+
+  /* We have a match for an overload instance, so add SYM to the current list
+   * of overload instances */
+  if (sym_return_val_index + 3 > sym_return_val_size)
+    {
+      newsize = (sym_return_val_size *= 2) * sizeof (struct symbol *);
+      sym_return_val = (struct symbol **) xrealloc ((char *) sym_return_val, newsize);
+    }
+  sym_return_val[sym_return_val_index++] = sym;
+  sym_return_val[sym_return_val_index] = NULL;
+}
+
+/* Return a null-terminated list of pointers to function symbols that
+ * match name of the supplied symbol FSYM.
+ * This is used in finding all overloaded instances of a function name.
+ * This has been modified from make_symbol_completion_list.  */
+
+
+struct symbol **
+make_symbol_overload_list (struct symbol *fsym)
+{
+  register struct symbol *sym;
+  register struct symtab *s;
+  register struct partial_symtab *ps;
+  register struct objfile *objfile;
+  register struct block *b, *surrounding_static_block = 0;
+  register int i;
+  /* The name we are completing on. */
+  char *oload_name = NULL;
+  /* Length of name.  */
+  int oload_name_len = 0;
+
+  /* Look for the symbol we are supposed to complete on.  */
+
+  oload_name = remove_params (SYMBOL_DEMANGLED_NAME (fsym));
+  if (!oload_name)
+    {
+      sym_return_val_size = 1;
+      sym_return_val = (struct symbol **) xmalloc (2 * sizeof (struct symbol *));
+      sym_return_val[0] = fsym;
+      sym_return_val[1] = NULL;
+
+      return sym_return_val;
+    }
+  oload_name_len = strlen (oload_name);
+
+  sym_return_val_size = 100;
+  sym_return_val_index = 0;
+  sym_return_val = (struct symbol **) xmalloc ((sym_return_val_size + 1) * sizeof (struct symbol *));
+  sym_return_val[0] = NULL;
+
+  /* Look through the partial symtabs for all symbols which begin
+     by matching OLOAD_NAME.  Make sure we read that symbol table in. */
+
+  ALL_PSYMTABS (objfile, ps)
+  {
+    struct partial_symbol **psym;
+
+    /* If the psymtab's been read in we'll get it when we search
+       through the blockvector.  */
+    if (ps->readin)
+      continue;
+
+    for (psym = objfile->global_psymbols.list + ps->globals_offset;
+        psym < (objfile->global_psymbols.list + ps->globals_offset
+                + ps->n_global_syms);
+        psym++)
+      {
+       /* If interrupted, then quit. */
+       QUIT;
+        /* This will cause the symbol table to be read if it has not yet been */
+        s = PSYMTAB_TO_SYMTAB (ps);
+      }
+
+    for (psym = objfile->static_psymbols.list + ps->statics_offset;
+        psym < (objfile->static_psymbols.list + ps->statics_offset
+                + ps->n_static_syms);
+        psym++)
+      {
+       QUIT;
+        /* This will cause the symbol table to be read if it has not yet been */
+        s = PSYMTAB_TO_SYMTAB (ps);
+      }
+  }
+
+  /* Search upwards from currently selected frame (so that we can
+     complete on local vars.  */
+
+  for (b = get_selected_block (0); b != NULL; b = BLOCK_SUPERBLOCK (b))
+    {
+      if (!BLOCK_SUPERBLOCK (b))
+       {
+         surrounding_static_block = b;         /* For elimination of dups */
+       }
+
+      /* Also catch fields of types defined in this places which match our
+         text string.  Only complete on types visible from current context. */
+
+      ALL_BLOCK_SYMBOLS (b, i, sym)
+       {
+         overload_list_add_symbol (sym, oload_name);
+       }
+    }
+
+  /* Go through the symtabs and check the externs and statics for
+     symbols which match.  */
+
+  ALL_SYMTABS (objfile, s)
+  {
+    QUIT;
+    b = BLOCKVECTOR_BLOCK (BLOCKVECTOR (s), GLOBAL_BLOCK);
+    ALL_BLOCK_SYMBOLS (b, i, sym)
+      {
+       overload_list_add_symbol (sym, oload_name);
+      }
+  }
+
+  ALL_SYMTABS (objfile, s)
+  {
+    QUIT;
+    b = BLOCKVECTOR_BLOCK (BLOCKVECTOR (s), STATIC_BLOCK);
+    /* Don't do this block twice.  */
+    if (b == surrounding_static_block)
+      continue;
+    ALL_BLOCK_SYMBOLS (b, i, sym)
+      {
+       overload_list_add_symbol (sym, oload_name);
+      }
+  }
+
+  xfree (oload_name);
+
+  return (sym_return_val);
+}
+
+/* End of overload resolution functions */
+\f
+struct symtabs_and_lines
+decode_line_spec (char *string, int funfirstline)
+{
+  struct symtabs_and_lines sals;
+  struct symtab_and_line cursal;
+  
+  if (string == 0)
+    error ("Empty line specification.");
+    
+  /* We use whatever is set as the current source line. We do not try
+     and get a default  or it will recursively call us! */  
+  cursal = get_current_source_symtab_and_line ();
+  
+  sals = decode_line_1 (&string, funfirstline,
+                       cursal.symtab, cursal.line,
+                       (char ***) NULL);
+
+  if (*string)
+    error ("Junk at end of line specification: %s", string);
+  return sals;
+}
+
+/* Track MAIN */
+static char *name_of_main;
+
+void
+set_main_name (const char *name)
+{
+  if (name_of_main != NULL)
+    {
+      xfree (name_of_main);
+      name_of_main = NULL;
+    }
+  if (name != NULL)
+    {
+      name_of_main = xstrdup (name);
+    }
+}
+
+char *
+main_name (void)
+{
+  if (name_of_main != NULL)
+    return name_of_main;
+  else
+    return "main";
+}
+
+
+void
+_initialize_symtab (void)
+{
+  add_info ("variables", variables_info,
+        "All global and static variable names, or those matching REGEXP.");
+  if (dbx_commands)
+    add_com ("whereis", class_info, variables_info,
+        "All global and static variable names, or those matching REGEXP.");
+
+  add_info ("functions", functions_info,
+           "All function names, or those matching REGEXP.");
+
+  
+  /* FIXME:  This command has at least the following problems:
+     1.  It prints builtin types (in a very strange and confusing fashion).
+     2.  It doesn't print right, e.g. with
+     typedef struct foo *FOO
+     type_print prints "FOO" when we want to make it (in this situation)
+     print "struct foo *".
+     I also think "ptype" or "whatis" is more likely to be useful (but if
+     there is much disagreement "info types" can be fixed).  */
+  add_info ("types", types_info,
+           "All type names, or those matching REGEXP.");
+
+#if 0
+  add_info ("methods", methods_info,
+           "All method names, or those matching REGEXP::REGEXP.\n\
+If the class qualifier is omitted, it is assumed to be the current scope.\n\
+If the first REGEXP is omitted, then all methods matching the second REGEXP\n\
+are listed.");
+#endif
+  add_info ("sources", sources_info,
+           "Source files in the program.");
+
+  add_com ("rbreak", class_breakpoint, rbreak_command,
+          "Set a breakpoint for all functions matching REGEXP.");
+
+  if (xdb_commands)
+    {
+      add_com ("lf", class_info, sources_info, "Source files in the program");
+      add_com ("lg", class_info, variables_info,
+        "All global and static variable names, or those matching REGEXP.");
+    }
+
+  /* Initialize the one built-in type that isn't language dependent... */
+  builtin_type_error = init_type (TYPE_CODE_ERROR, 0, 0,
+                                 "<unknown type>", (struct objfile *) NULL);
+}
diff --git a/gdb/symtab.h b/gdb/symtab.h
new file mode 100644 (file)
index 0000000..a78607d
--- /dev/null
@@ -0,0 +1,1414 @@
+/* Symbol table definitions for GDB.
+   Copyright 1986, 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1995, 1996,
+   1997, 1998, 1999, 2000, 2001, 2002
+   Free Software Foundation, Inc.
+
+   This file is part of GDB.
+
+   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.  */
+
+#if !defined (SYMTAB_H)
+#define SYMTAB_H 1
+
+/* Opaque declarations.  */
+struct obstack;
+
+/* Don't do this; it means that if some .o's are compiled with GNU C
+   and some are not (easy to do accidentally the way we configure
+   things; also it is a pain to have to "make clean" every time you
+   want to switch compilers), then GDB dies a horrible death.  */
+/* GNU C supports enums that are bitfields.  Some compilers don't. */
+#if 0 && defined(__GNUC__) && !defined(BYTE_BITFIELD)
+#define        BYTE_BITFIELD   :8;
+#else
+#define        BYTE_BITFIELD           /*nothing */
+#endif
+
+/* Define a structure for the information that is common to all symbol types,
+   including minimal symbols, partial symbols, and full symbols.  In a
+   multilanguage environment, some language specific information may need to
+   be recorded along with each symbol.
+
+   These fields are ordered to encourage good packing, since we frequently
+   have tens or hundreds of thousands of these.  */
+
+struct general_symbol_info
+{
+  /* Name of the symbol.  This is a required field.  Storage for the name is
+     allocated on the psymbol_obstack or symbol_obstack for the associated
+     objfile. */
+
+  char *name;
+
+  /* Value of the symbol.  Which member of this union to use, and what
+     it means, depends on what kind of symbol this is and its
+     SYMBOL_CLASS.  See comments there for more details.  All of these
+     are in host byte order (though what they point to might be in
+     target byte order, e.g. LOC_CONST_BYTES).  */
+
+  union
+  {
+    /* The fact that this is a long not a LONGEST mainly limits the
+       range of a LOC_CONST.  Since LOC_CONST_BYTES exists, I'm not
+       sure that is a big deal.  */
+    long ivalue;
+
+    struct block *block;
+
+    char *bytes;
+
+    CORE_ADDR address;
+
+    /* for opaque typedef struct chain */
+
+    struct symbol *chain;
+  }
+  value;
+
+  /* Since one and only one language can apply, wrap the language specific
+     information inside a union. */
+
+  union
+  {
+    struct cplus_specific      /* For C++ */
+      /*  and Java */
+    {
+      char *demangled_name;
+    }
+    cplus_specific;
+#if 0
+/* OBSOLETE struct chill_specific        *//* For Chill */
+    /* OBSOLETE   { */
+    /* OBSOLETE     char *demangled_name; */
+    /* OBSOLETE   } */
+    /* OBSOLETE chill_specific; */
+#endif
+  }
+  language_specific;
+
+  /* Record the source code language that applies to this symbol.
+     This is used to select one of the fields from the language specific
+     union above. */
+
+  enum language language BYTE_BITFIELD;
+
+  /* Which section is this symbol in?  This is an index into
+     section_offsets for this objfile.  Negative means that the symbol
+     does not get relocated relative to a section.
+     Disclaimer: currently this is just used for xcoff, so don't
+     expect all symbol-reading code to set it correctly (the ELF code
+     also tries to set it correctly).  */
+
+  short section;
+
+  /* The bfd section associated with this symbol. */
+
+  asection *bfd_section;
+};
+
+extern CORE_ADDR symbol_overlayed_address (CORE_ADDR, asection *);
+
+#define SYMBOL_NAME(symbol)            (symbol)->ginfo.name
+#define SYMBOL_VALUE(symbol)           (symbol)->ginfo.value.ivalue
+#define SYMBOL_VALUE_ADDRESS(symbol)   (symbol)->ginfo.value.address
+#define SYMBOL_VALUE_BYTES(symbol)     (symbol)->ginfo.value.bytes
+#define SYMBOL_BLOCK_VALUE(symbol)     (symbol)->ginfo.value.block
+#define SYMBOL_VALUE_CHAIN(symbol)     (symbol)->ginfo.value.chain
+#define SYMBOL_LANGUAGE(symbol)                (symbol)->ginfo.language
+#define SYMBOL_SECTION(symbol)         (symbol)->ginfo.section
+#define SYMBOL_BFD_SECTION(symbol)     (symbol)->ginfo.bfd_section
+
+#define SYMBOL_CPLUS_DEMANGLED_NAME(symbol)    \
+  (symbol)->ginfo.language_specific.cplus_specific.demangled_name
+
+/* Macro that initializes the language dependent portion of a symbol
+   depending upon the language for the symbol. */
+
+#define SYMBOL_INIT_LANGUAGE_SPECIFIC(symbol,language)                 \
+  do {                                                                 \
+    SYMBOL_LANGUAGE (symbol) = language;                               \
+    if (SYMBOL_LANGUAGE (symbol) == language_cplus                     \
+       || SYMBOL_LANGUAGE (symbol) == language_java                    \
+       )                                                               \
+      {                                                                        \
+       SYMBOL_CPLUS_DEMANGLED_NAME (symbol) = NULL;                    \
+      }                                                                        \
+    /* OBSOLETE else if (SYMBOL_LANGUAGE (symbol) == language_chill) */ \
+    /* OBSOLETE   { */                                                 \
+    /* OBSOLETE     SYMBOL_CHILL_DEMANGLED_NAME (symbol) = NULL; */    \
+    /* OBSOLETE   } */                                                 \
+    else                                                               \
+      {                                                                        \
+       memset (&(symbol)->ginfo.language_specific, 0,                  \
+               sizeof ((symbol)->ginfo.language_specific));            \
+      }                                                                        \
+  } while (0)
+
+#define SYMBOL_INIT_DEMANGLED_NAME(symbol,obstack) \
+  (symbol_init_demangled_name (&symbol->ginfo, (obstack)))
+extern void symbol_init_demangled_name (struct general_symbol_info *symbol,
+                                       struct obstack *obstack);
+
+
+/* Macro that returns the demangled name for a symbol based on the language
+   for that symbol.  If no demangled name exists, returns NULL. */
+
+#define SYMBOL_DEMANGLED_NAME(symbol)                                  \
+  (SYMBOL_LANGUAGE (symbol) == language_cplus                          \
+   || SYMBOL_LANGUAGE (symbol) == language_java                                \
+   ? SYMBOL_CPLUS_DEMANGLED_NAME (symbol)                              \
+   : /* OBSOLETE (SYMBOL_LANGUAGE (symbol) == language_chill */                \
+     /* OBSOLETE ? SYMBOL_CHILL_DEMANGLED_NAME (symbol) */             \
+     NULL)
+
+/* OBSOLETE #define SYMBOL_CHILL_DEMANGLED_NAME(symbol) */
+/* OBSOLETE (symbol)->ginfo.language_specific.chill_specific.demangled_name */
+
+/* Macro that returns the "natural source name" of a symbol.  In C++ this is
+   the "demangled" form of the name if demangle is on and the "mangled" form
+   of the name if demangle is off.  In other languages this is just the
+   symbol name.  The result should never be NULL. */
+
+#define SYMBOL_SOURCE_NAME(symbol)                                     \
+  (demangle && SYMBOL_DEMANGLED_NAME (symbol) != NULL                  \
+   ? SYMBOL_DEMANGLED_NAME (symbol)                                    \
+   : SYMBOL_NAME (symbol))
+
+/* Macro that returns the "natural assembly name" of a symbol.  In C++ this is
+   the "mangled" form of the name if demangle is off, or if demangle is on and
+   asm_demangle is off.  Otherwise if asm_demangle is on it is the "demangled"
+   form.  In other languages this is just the symbol name.  The result should
+   never be NULL. */
+
+#define SYMBOL_LINKAGE_NAME(symbol)                                    \
+  (demangle && asm_demangle && SYMBOL_DEMANGLED_NAME (symbol) != NULL  \
+   ? SYMBOL_DEMANGLED_NAME (symbol)                                    \
+   : SYMBOL_NAME (symbol))
+
+/* Macro that tests a symbol for a match against a specified name string.
+   First test the unencoded name, then looks for and test a C++ encoded
+   name if it exists.  Note that whitespace is ignored while attempting to
+   match a C++ encoded name, so that "foo::bar(int,long)" is the same as
+   "foo :: bar (int, long)".
+   Evaluates to zero if the match fails, or nonzero if it succeeds. */
+
+#define SYMBOL_MATCHES_NAME(symbol, name)                              \
+  (STREQ (SYMBOL_NAME (symbol), (name))                                        \
+   || (SYMBOL_DEMANGLED_NAME (symbol) != NULL                          \
+       && strcmp_iw (SYMBOL_DEMANGLED_NAME (symbol), (name)) == 0))
+
+/* Macro that tests a symbol for an re-match against the last compiled regular
+   expression.  First test the unencoded name, then look for and test a C++
+   encoded name if it exists.
+   Evaluates to zero if the match fails, or nonzero if it succeeds. */
+
+#define SYMBOL_MATCHES_REGEXP(symbol)                                  \
+  (re_exec (SYMBOL_NAME (symbol)) != 0                                 \
+   || (SYMBOL_DEMANGLED_NAME (symbol) != NULL                          \
+       && re_exec (SYMBOL_DEMANGLED_NAME (symbol)) != 0))
+
+/* Define a simple structure used to hold some very basic information about
+   all defined global symbols (text, data, bss, abs, etc).  The only required
+   information is the general_symbol_info.
+
+   In many cases, even if a file was compiled with no special options for
+   debugging at all, as long as was not stripped it will contain sufficient
+   information to build a useful minimal symbol table using this structure.
+   Even when a file contains enough debugging information to build a full
+   symbol table, these minimal symbols are still useful for quickly mapping
+   between names and addresses, and vice versa.  They are also sometimes
+   used to figure out what full symbol table entries need to be read in. */
+
+struct minimal_symbol
+{
+
+  /* The general symbol info required for all types of symbols.
+
+     The SYMBOL_VALUE_ADDRESS contains the address that this symbol
+     corresponds to.  */
+
+  struct general_symbol_info ginfo;
+
+  /* The info field is available for caching machine-specific information
+     so it doesn't have to rederive the info constantly (over a serial line).
+     It is initialized to zero and stays that way until target-dependent code
+     sets it.  Storage for any data pointed to by this field should be allo-
+     cated on the symbol_obstack for the associated objfile.  
+     The type would be "void *" except for reasons of compatibility with older
+     compilers.  This field is optional.
+
+     Currently, the AMD 29000 tdep.c uses it to remember things it has decoded
+     from the instructions in the function header, and the MIPS-16 code uses
+     it to identify 16-bit procedures.  */
+
+  char *info;
+
+#ifdef SOFUN_ADDRESS_MAYBE_MISSING
+  /* Which source file is this symbol in?  Only relevant for mst_file_*.  */
+  char *filename;
+#endif
+
+  /* Classification types for this symbol.  These should be taken as "advisory
+     only", since if gdb can't easily figure out a classification it simply
+     selects mst_unknown.  It may also have to guess when it can't figure out
+     which is a better match between two types (mst_data versus mst_bss) for
+     example.  Since the minimal symbol info is sometimes derived from the
+     BFD library's view of a file, we need to live with what information bfd
+     supplies. */
+
+  enum minimal_symbol_type
+  {
+    mst_unknown = 0,           /* Unknown type, the default */
+    mst_text,                  /* Generally executable instructions */
+    mst_data,                  /* Generally initialized data */
+    mst_bss,                   /* Generally uninitialized data */
+    mst_abs,                   /* Generally absolute (nonrelocatable) */
+    /* GDB uses mst_solib_trampoline for the start address of a shared
+       library trampoline entry.  Breakpoints for shared library functions
+       are put there if the shared library is not yet loaded.
+       After the shared library is loaded, lookup_minimal_symbol will
+       prefer the minimal symbol from the shared library (usually
+       a mst_text symbol) over the mst_solib_trampoline symbol, and the
+       breakpoints will be moved to their true address in the shared
+       library via breakpoint_re_set.  */
+    mst_solib_trampoline,      /* Shared library trampoline code */
+    /* For the mst_file* types, the names are only guaranteed to be unique
+       within a given .o file.  */
+    mst_file_text,             /* Static version of mst_text */
+    mst_file_data,             /* Static version of mst_data */
+    mst_file_bss               /* Static version of mst_bss */
+  }
+  type BYTE_BITFIELD;
+
+  /* Minimal symbols with the same hash key are kept on a linked
+     list.  This is the link.  */
+
+  struct minimal_symbol *hash_next;
+
+  /* Minimal symbols are stored in two different hash tables.  This is
+     the `next' pointer for the demangled hash table.  */
+
+  struct minimal_symbol *demangled_hash_next;
+};
+
+#define MSYMBOL_INFO(msymbol)          (msymbol)->info
+#define MSYMBOL_TYPE(msymbol)          (msymbol)->type
+\f
+
+
+/* All of the name-scope contours of the program
+   are represented by `struct block' objects.
+   All of these objects are pointed to by the blockvector.
+
+   Each block represents one name scope.
+   Each lexical context has its own block.
+
+   The blockvector begins with some special blocks.
+   The GLOBAL_BLOCK contains all the symbols defined in this compilation
+   whose scope is the entire program linked together.
+   The STATIC_BLOCK contains all the symbols whose scope is the
+   entire compilation excluding other separate compilations.
+   Blocks starting with the FIRST_LOCAL_BLOCK are not special.
+
+   Each block records a range of core addresses for the code that
+   is in the scope of the block.  The STATIC_BLOCK and GLOBAL_BLOCK
+   give, for the range of code, the entire range of code produced
+   by the compilation that the symbol segment belongs to.
+
+   The blocks appear in the blockvector
+   in order of increasing starting-address,
+   and, within that, in order of decreasing ending-address.
+
+   This implies that within the body of one function
+   the blocks appear in the order of a depth-first tree walk.  */
+
+struct blockvector
+{
+  /* Number of blocks in the list.  */
+  int nblocks;
+  /* The blocks themselves.  */
+  struct block *block[1];
+};
+
+#define BLOCKVECTOR_NBLOCKS(blocklist) (blocklist)->nblocks
+#define BLOCKVECTOR_BLOCK(blocklist,n) (blocklist)->block[n]
+
+/* Special block numbers */
+
+#define GLOBAL_BLOCK           0
+#define        STATIC_BLOCK            1
+#define        FIRST_LOCAL_BLOCK       2
+
+struct block
+{
+
+  /* Addresses in the executable code that are in this block.  */
+
+  CORE_ADDR startaddr;
+  CORE_ADDR endaddr;
+
+  /* The symbol that names this block, if the block is the body of a
+     function; otherwise, zero.  */
+
+  struct symbol *function;
+
+  /* The `struct block' for the containing block, or 0 if none.
+
+     The superblock of a top-level local block (i.e. a function in the
+     case of C) is the STATIC_BLOCK.  The superblock of the
+     STATIC_BLOCK is the GLOBAL_BLOCK.  */
+
+  struct block *superblock;
+
+  /* Version of GCC used to compile the function corresponding
+     to this block, or 0 if not compiled with GCC.  When possible,
+     GCC should be compatible with the native compiler, or if that
+     is not feasible, the differences should be fixed during symbol
+     reading.  As of 16 Apr 93, this flag is never used to distinguish
+     between gcc2 and the native compiler.
+
+     If there is no function corresponding to this block, this meaning
+     of this flag is undefined.  */
+
+  unsigned char gcc_compile_flag;
+
+  /* The symbols for this block are either in a simple linear list or
+     in a simple hashtable.  Blocks which correspond to a function
+     (which have a list of symbols corresponding to arguments) use
+     a linear list, as do some older symbol readers (currently only
+     mdebugread and dstread).  Other blocks are hashed.
+
+     The hashtable uses the same hash function as the minsym hashtables,
+     found in minsyms.c:minsym_hash_iw.  Symbols are hashed based on
+     their demangled name if appropriate, and on their name otherwise.
+     The hash function ignores space, and stops at the beginning of the
+     argument list if any.
+
+     The table is laid out in NSYMS/5 buckets and symbols are chained via
+     their hash_next field.  */
+
+  /* If this is really a hashtable of the symbols, this flag is 1.  */
+
+  unsigned char hashtable;
+
+  /* Number of local symbols.  */
+
+  int nsyms;
+
+  /* The symbols.  If some of them are arguments, then they must be
+     in the order in which we would like to print them.  */
+
+  struct symbol *sym[1];
+};
+
+#define BLOCK_START(bl)                (bl)->startaddr
+#define BLOCK_END(bl)          (bl)->endaddr
+#define BLOCK_FUNCTION(bl)     (bl)->function
+#define BLOCK_SUPERBLOCK(bl)   (bl)->superblock
+#define BLOCK_GCC_COMPILED(bl) (bl)->gcc_compile_flag
+#define BLOCK_HASHTABLE(bl)    (bl)->hashtable
+
+/* For blocks without a hashtable (BLOCK_HASHTABLE (bl) == 0) only.  */
+#define BLOCK_NSYMS(bl)                (bl)->nsyms
+#define BLOCK_SYM(bl, n)       (bl)->sym[n]
+
+/* For blocks with a hashtable, but these are valid for non-hashed blocks as
+   well - each symbol will appear to be one bucket by itself.  */
+#define BLOCK_BUCKETS(bl)      (bl)->nsyms
+#define BLOCK_BUCKET(bl, n)    (bl)->sym[n]
+
+/* Macro used to set the size of a hashtable for N symbols.  */
+#define BLOCK_HASHTABLE_SIZE(n)        ((n)/5 + 1)
+
+/* Macro to loop through all symbols in a block BL, in no particular order.
+   i counts which bucket we are in, and sym points to the current symbol.  */
+
+#define ALL_BLOCK_SYMBOLS(bl, i, sym)                          \
+       for ((i) = 0; (i) < BLOCK_BUCKETS ((bl)); (i)++)        \
+         for ((sym) = BLOCK_BUCKET ((bl), (i)); (sym);         \
+              (sym) = (sym)->hash_next)
+
+/* Nonzero if symbols of block BL should be sorted alphabetically.
+   Don't sort a block which corresponds to a function.  If we did the
+   sorting would have to preserve the order of the symbols for the
+   arguments.  Also don't sort any block that we chose to hash.  */
+
+#define BLOCK_SHOULD_SORT(bl) (! BLOCK_HASHTABLE (bl) \
+                              && BLOCK_FUNCTION (bl) == NULL)
+\f
+
+/* Represent one symbol name; a variable, constant, function or typedef.  */
+
+/* Different name spaces for symbols.  Looking up a symbol specifies a
+   namespace and ignores symbol definitions in other name spaces. */
+
+typedef enum
+{
+  /* UNDEF_NAMESPACE is used when a namespace has not been discovered or
+     none of the following apply.  This usually indicates an error either
+     in the symbol information or in gdb's handling of symbols. */
+
+  UNDEF_NAMESPACE,
+
+  /* VAR_NAMESPACE is the usual namespace.  In C, this contains variables,
+     function names, typedef names and enum type values. */
+
+  VAR_NAMESPACE,
+
+  /* STRUCT_NAMESPACE is used in C to hold struct, union and enum type names.
+     Thus, if `struct foo' is used in a C program, it produces a symbol named
+     `foo' in the STRUCT_NAMESPACE. */
+
+  STRUCT_NAMESPACE,
+
+  /* LABEL_NAMESPACE may be used for names of labels (for gotos);
+     currently it is not used and labels are not recorded at all.  */
+
+  LABEL_NAMESPACE,
+
+  /* Searching namespaces. These overlap with VAR_NAMESPACE, providing
+     some granularity with the search_symbols function. */
+
+  /* Everything in VAR_NAMESPACE minus FUNCTIONS_-, TYPES_-, and
+     METHODS_NAMESPACE */
+  VARIABLES_NAMESPACE,
+
+  /* All functions -- for some reason not methods, though. */
+  FUNCTIONS_NAMESPACE,
+
+  /* All defined types */
+  TYPES_NAMESPACE,
+
+  /* All class methods -- why is this separated out? */
+  METHODS_NAMESPACE
+}
+namespace_enum;
+
+/* An address-class says where to find the value of a symbol.  */
+
+enum address_class
+{
+  /* Not used; catches errors */
+
+  LOC_UNDEF,
+
+  /* Value is constant int SYMBOL_VALUE, host byteorder */
+
+  LOC_CONST,
+
+  /* Value is at fixed address SYMBOL_VALUE_ADDRESS */
+
+  LOC_STATIC,
+
+  /* Value is in register.  SYMBOL_VALUE is the register number.  */
+
+  LOC_REGISTER,
+
+  /* It's an argument; the value is at SYMBOL_VALUE offset in arglist.  */
+
+  LOC_ARG,
+
+  /* Value address is at SYMBOL_VALUE offset in arglist.  */
+
+  LOC_REF_ARG,
+
+  /* Value is in register number SYMBOL_VALUE.  Just like LOC_REGISTER
+     except this is an argument.  Probably the cleaner way to handle
+     this would be to separate address_class (which would include
+     separate ARG and LOCAL to deal with FRAME_ARGS_ADDRESS versus
+     FRAME_LOCALS_ADDRESS), and an is_argument flag.
+
+     For some symbol formats (stabs, for some compilers at least),
+     the compiler generates two symbols, an argument and a register.
+     In some cases we combine them to a single LOC_REGPARM in symbol
+     reading, but currently not for all cases (e.g. it's passed on the
+     stack and then loaded into a register).  */
+
+  LOC_REGPARM,
+
+  /* Value is in specified register.  Just like LOC_REGPARM except the
+     register holds the address of the argument instead of the argument
+     itself. This is currently used for the passing of structs and unions
+     on sparc and hppa.  It is also used for call by reference where the
+     address is in a register, at least by mipsread.c.  */
+
+  LOC_REGPARM_ADDR,
+
+  /* Value is a local variable at SYMBOL_VALUE offset in stack frame.  */
+
+  LOC_LOCAL,
+
+  /* Value not used; definition in SYMBOL_TYPE.  Symbols in the namespace
+     STRUCT_NAMESPACE all have this class.  */
+
+  LOC_TYPEDEF,
+
+  /* Value is address SYMBOL_VALUE_ADDRESS in the code */
+
+  LOC_LABEL,
+
+  /* In a symbol table, value is SYMBOL_BLOCK_VALUE of a `struct block'.
+     In a partial symbol table, SYMBOL_VALUE_ADDRESS is the start address
+     of the block.  Function names have this class. */
+
+  LOC_BLOCK,
+
+  /* Value is a constant byte-sequence pointed to by SYMBOL_VALUE_BYTES, in
+     target byte order.  */
+
+  LOC_CONST_BYTES,
+
+  /* Value is arg at SYMBOL_VALUE offset in stack frame. Differs from
+     LOC_LOCAL in that symbol is an argument; differs from LOC_ARG in
+     that we find it in the frame (FRAME_LOCALS_ADDRESS), not in the
+     arglist (FRAME_ARGS_ADDRESS).  Added for i960, which passes args
+     in regs then copies to frame.  */
+
+  LOC_LOCAL_ARG,
+
+  /* Value is at SYMBOL_VALUE offset from the current value of
+     register number SYMBOL_BASEREG.  This exists mainly for the same
+     things that LOC_LOCAL and LOC_ARG do; but we need to do this
+     instead because on 88k DWARF gives us the offset from the
+     frame/stack pointer, rather than the offset from the "canonical
+     frame address" used by COFF, stabs, etc., and we don't know how
+     to convert between these until we start examining prologues.
+
+     Note that LOC_BASEREG is much less general than a DWARF expression.
+     We don't need the generality (at least not yet), and storing a general
+     DWARF expression would presumably take up more space than the existing
+     scheme.  */
+
+  LOC_BASEREG,
+
+  /* Same as LOC_BASEREG but it is an argument.  */
+
+  LOC_BASEREG_ARG,
+
+  /* Value is at fixed address, but the address of the variable has
+     to be determined from the minimal symbol table whenever the
+     variable is referenced.
+     This happens if debugging information for a global symbol is
+     emitted and the corresponding minimal symbol is defined
+     in another object file or runtime common storage.
+     The linker might even remove the minimal symbol if the global
+     symbol is never referenced, in which case the symbol remains
+     unresolved.  */
+
+  LOC_UNRESOLVED,
+
+  /* Value is at a thread-specific location calculated by a
+     target-specific method. */
+
+  LOC_THREAD_LOCAL_STATIC,
+
+  /* The variable does not actually exist in the program.
+     The value is ignored.  */
+
+  LOC_OPTIMIZED_OUT,
+
+  /* The variable is static, but actually lives at * (address).
+   * I.e. do an extra indirection to get to it.
+   * This is used on HP-UX to get at globals that are allocated
+   * in shared libraries, where references from images other
+   * than the one where the global was allocated are done
+   * with a level of indirection.
+   */
+
+  LOC_INDIRECT
+};
+
+/* Linked list of symbol's live ranges. */
+
+struct range_list
+{
+  CORE_ADDR start;
+  CORE_ADDR end;
+  struct range_list *next;
+};
+
+/* Linked list of aliases for a particular main/primary symbol.  */
+struct alias_list
+{
+  struct symbol *sym;
+  struct alias_list *next;
+};
+
+struct symbol
+{
+
+  /* The general symbol info required for all types of symbols. */
+
+  struct general_symbol_info ginfo;
+
+  /* Data type of value */
+
+  struct type *type;
+
+  /* Name space code.  */
+
+#ifdef __MFC4__
+  /* FIXME: don't conflict with C++'s namespace */
+  /* would be safer to do a global change for all namespace identifiers. */
+#define namespace _namespace
+#endif
+  namespace_enum namespace BYTE_BITFIELD;
+
+  /* Address class */
+
+  enum address_class aclass BYTE_BITFIELD;
+
+  /* Line number of definition.  FIXME:  Should we really make the assumption
+     that nobody will try to debug files longer than 64K lines?  What about
+     machine generated programs? */
+
+  unsigned short line;
+
+  /* Some symbols require an additional value to be recorded on a per-
+     symbol basis.  Stash those values here. */
+
+  union
+  {
+    /* Used by LOC_BASEREG and LOC_BASEREG_ARG.  */
+    short basereg;
+  }
+  aux_value;
+
+
+  /* Link to a list of aliases for this symbol.
+     Only a "primary/main symbol may have aliases.  */
+  struct alias_list *aliases;
+
+  /* List of ranges where this symbol is active.  This is only
+     used by alias symbols at the current time.  */
+  struct range_list *ranges;
+
+  struct symbol *hash_next;
+};
+
+
+#define SYMBOL_NAMESPACE(symbol)       (symbol)->namespace
+#define SYMBOL_CLASS(symbol)           (symbol)->aclass
+#define SYMBOL_TYPE(symbol)            (symbol)->type
+#define SYMBOL_LINE(symbol)            (symbol)->line
+#define SYMBOL_BASEREG(symbol)         (symbol)->aux_value.basereg
+#define SYMBOL_ALIASES(symbol)         (symbol)->aliases
+#define SYMBOL_RANGES(symbol)          (symbol)->ranges
+\f
+/* A partial_symbol records the name, namespace, and address class of
+   symbols whose types we have not parsed yet.  For functions, it also
+   contains their memory address, so we can find them from a PC value.
+   Each partial_symbol sits in a partial_symtab, all of which are chained
+   on a  partial symtab list and which points to the corresponding 
+   normal symtab once the partial_symtab has been referenced.  */
+
+struct partial_symbol
+{
+
+  /* The general symbol info required for all types of symbols. */
+
+  struct general_symbol_info ginfo;
+
+  /* Name space code.  */
+
+  namespace_enum namespace BYTE_BITFIELD;
+
+  /* Address class (for info_symbols) */
+
+  enum address_class aclass BYTE_BITFIELD;
+
+};
+
+#define PSYMBOL_NAMESPACE(psymbol)     (psymbol)->namespace
+#define PSYMBOL_CLASS(psymbol)         (psymbol)->aclass
+\f
+
+/* Source-file information.  This describes the relation between source files,
+   line numbers and addresses in the program text.  */
+
+struct sourcevector
+{
+  int length;                  /* Number of source files described */
+  struct source *source[1];    /* Descriptions of the files */
+};
+
+/* Each item represents a line-->pc (or the reverse) mapping.  This is
+   somewhat more wasteful of space than one might wish, but since only
+   the files which are actually debugged are read in to core, we don't
+   waste much space.  */
+
+struct linetable_entry
+{
+  int line;
+  CORE_ADDR pc;
+};
+
+/* The order of entries in the linetable is significant.  They should
+   be sorted by increasing values of the pc field.  If there is more than
+   one entry for a given pc, then I'm not sure what should happen (and
+   I not sure whether we currently handle it the best way).
+
+   Example: a C for statement generally looks like this
+
+   10   0x100   - for the init/test part of a for stmt.
+   20   0x200
+   30   0x300
+   10   0x400   - for the increment part of a for stmt.
+
+   If an entry has a line number of zero, it marks the start of a PC
+   range for which no line number information is available.  It is
+   acceptable, though wasteful of table space, for such a range to be
+   zero length.  */
+
+struct linetable
+{
+  int nitems;
+
+  /* Actually NITEMS elements.  If you don't like this use of the
+     `struct hack', you can shove it up your ANSI (seriously, if the
+     committee tells us how to do it, we can probably go along).  */
+  struct linetable_entry item[1];
+};
+
+/* All the information on one source file.  */
+
+struct source
+{
+  char *name;                  /* Name of file */
+  struct linetable contents;
+};
+
+/* How to relocate the symbols from each section in a symbol file.
+   Each struct contains an array of offsets.
+   The ordering and meaning of the offsets is file-type-dependent;
+   typically it is indexed by section numbers or symbol types or
+   something like that.
+
+   To give us flexibility in changing the internal representation
+   of these offsets, the ANOFFSET macro must be used to insert and
+   extract offset values in the struct.  */
+
+struct section_offsets
+{
+  CORE_ADDR offsets[1];                /* As many as needed. */
+};
+
+#define        ANOFFSET(secoff, whichone) \
+   ((whichone == -1) \
+    ? (internal_error (__FILE__, __LINE__, "Section index is uninitialized"), -1) \
+    : secoff->offsets[whichone])
+
+/* The maximum possible size of a section_offsets table.  */
+
+#define SIZEOF_SECTION_OFFSETS \
+  (sizeof (struct section_offsets) \
+   + sizeof (((struct section_offsets *) 0)->offsets) * (SECT_OFF_MAX-1))
+
+/* Each source file or header is represented by a struct symtab. 
+   These objects are chained through the `next' field.  */
+
+struct symtab
+{
+
+  /* Chain of all existing symtabs.  */
+
+  struct symtab *next;
+
+  /* List of all symbol scope blocks for this symtab.  May be shared
+     between different symtabs (and normally is for all the symtabs
+     in a given compilation unit).  */
+
+  struct blockvector *blockvector;
+
+  /* Table mapping core addresses to line numbers for this file.
+     Can be NULL if none.  Never shared between different symtabs.  */
+
+  struct linetable *linetable;
+
+  /* Section in objfile->section_offsets for the blockvector and
+     the linetable.  Probably always SECT_OFF_TEXT.  */
+
+  int block_line_section;
+
+  /* If several symtabs share a blockvector, exactly one of them
+     should be designated the primary, so that the blockvector
+     is relocated exactly once by objfile_relocate.  */
+
+  int primary;
+
+  /* The macro table for this symtab.  Like the blockvector, this
+     may be shared between different symtabs --- and normally is for
+     all the symtabs in a given compilation unit.  */
+  struct macro_table *macro_table;
+
+  /* Name of this source file.  */
+
+  char *filename;
+
+  /* Directory in which it was compiled, or NULL if we don't know.  */
+
+  char *dirname;
+
+  /* This component says how to free the data we point to:
+     free_contents => do a tree walk and free each object.
+     free_nothing => do nothing; some other symtab will free
+     the data this one uses.
+     free_linetable => free just the linetable.  FIXME: Is this redundant
+     with the primary field?  */
+
+  enum free_code
+  {
+    free_nothing, free_contents, free_linetable
+  }
+  free_code;
+
+  /* Pointer to one block of storage to be freed, if nonzero.  */
+  /* This is IN ADDITION to the action indicated by free_code.  */
+
+  char *free_ptr;
+
+  /* Total number of lines found in source file.  */
+
+  int nlines;
+
+  /* line_charpos[N] is the position of the (N-1)th line of the
+     source file.  "position" means something we can lseek() to; it
+     is not guaranteed to be useful any other way.  */
+
+  int *line_charpos;
+
+  /* Language of this source file.  */
+
+  enum language language;
+
+  /* String that identifies the format of the debugging information, such
+     as "stabs", "dwarf 1", "dwarf 2", "coff", etc.  This is mostly useful
+     for automated testing of gdb but may also be information that is
+     useful to the user. */
+
+  char *debugformat;
+
+  /* String of version information.  May be zero.  */
+
+  char *version;
+
+  /* Full name of file as found by searching the source path.
+     NULL if not yet known.  */
+
+  char *fullname;
+
+  /* Object file from which this symbol information was read.  */
+
+  struct objfile *objfile;
+
+};
+
+#define BLOCKVECTOR(symtab)    (symtab)->blockvector
+#define LINETABLE(symtab)      (symtab)->linetable
+\f
+
+/* Each source file that has not been fully read in is represented by
+   a partial_symtab.  This contains the information on where in the
+   executable the debugging symbols for a specific file are, and a
+   list of names of global symbols which are located in this file.
+   They are all chained on partial symtab lists.
+
+   Even after the source file has been read into a symtab, the
+   partial_symtab remains around.  They are allocated on an obstack,
+   psymbol_obstack.  FIXME, this is bad for dynamic linking or VxWorks-
+   style execution of a bunch of .o's.  */
+
+struct partial_symtab
+{
+
+  /* Chain of all existing partial symtabs.  */
+
+  struct partial_symtab *next;
+
+  /* Name of the source file which this partial_symtab defines */
+
+  char *filename;
+
+  /* Full path of the source file.  NULL if not known.  */
+
+  char *fullname;
+
+  /* Information about the object file from which symbols should be read.  */
+
+  struct objfile *objfile;
+
+  /* Set of relocation offsets to apply to each section.  */
+
+  struct section_offsets *section_offsets;
+
+  /* Range of text addresses covered by this file; texthigh is the
+     beginning of the next section. */
+
+  CORE_ADDR textlow;
+  CORE_ADDR texthigh;
+
+  /* Array of pointers to all of the partial_symtab's which this one
+     depends on.  Since this array can only be set to previous or
+     the current (?) psymtab, this dependency tree is guaranteed not
+     to have any loops.  "depends on" means that symbols must be read
+     for the dependencies before being read for this psymtab; this is
+     for type references in stabs, where if foo.c includes foo.h, declarations
+     in foo.h may use type numbers defined in foo.c.  For other debugging
+     formats there may be no need to use dependencies.  */
+
+  struct partial_symtab **dependencies;
+
+  int number_of_dependencies;
+
+  /* Global symbol list.  This list will be sorted after readin to
+     improve access.  Binary search will be the usual method of
+     finding a symbol within it. globals_offset is an integer offset
+     within global_psymbols[].  */
+
+  int globals_offset;
+  int n_global_syms;
+
+  /* Static symbol list.  This list will *not* be sorted after readin;
+     to find a symbol in it, exhaustive search must be used.  This is
+     reasonable because searches through this list will eventually
+     lead to either the read in of a files symbols for real (assumed
+     to take a *lot* of time; check) or an error (and we don't care
+     how long errors take).  This is an offset and size within
+     static_psymbols[].  */
+
+  int statics_offset;
+  int n_static_syms;
+
+  /* Pointer to symtab eventually allocated for this source file, 0 if
+     !readin or if we haven't looked for the symtab after it was readin.  */
+
+  struct symtab *symtab;
+
+  /* Pointer to function which will read in the symtab corresponding to
+     this psymtab.  */
+
+  void (*read_symtab) (struct partial_symtab *);
+
+  /* Information that lets read_symtab() locate the part of the symbol table
+     that this psymtab corresponds to.  This information is private to the
+     format-dependent symbol reading routines.  For further detail examine
+     the various symbol reading modules.  Should really be (void *) but is
+     (char *) as with other such gdb variables.  (FIXME) */
+
+  char *read_symtab_private;
+
+  /* Non-zero if the symtab corresponding to this psymtab has been readin */
+
+  unsigned char readin;
+};
+
+/* A fast way to get from a psymtab to its symtab (after the first time).  */
+#define        PSYMTAB_TO_SYMTAB(pst)  \
+    ((pst) -> symtab != NULL ? (pst) -> symtab : psymtab_to_symtab (pst))
+\f
+
+/* The virtual function table is now an array of structures which have the
+   form { int16 offset, delta; void *pfn; }. 
+
+   In normal virtual function tables, OFFSET is unused.
+   DELTA is the amount which is added to the apparent object's base
+   address in order to point to the actual object to which the
+   virtual function should be applied.
+   PFN is a pointer to the virtual function.
+
+   Note that this macro is g++ specific (FIXME). */
+
+#define VTBL_FNADDR_OFFSET 2
+
+/* External variables and functions for the objects described above. */
+
+/* See the comment in symfile.c about how current_objfile is used. */
+
+extern struct objfile *current_objfile;
+
+/* True if we are nested inside psymtab_to_symtab. */
+
+extern int currently_reading_symtab;
+
+/* From utils.c.  */
+extern int demangle;
+extern int asm_demangle;
+
+/* symtab.c lookup functions */
+
+/* lookup a symbol table by source file name */
+
+extern struct symtab *lookup_symtab (const char *);
+
+/* lookup a symbol by name (optional block, optional symtab) */
+
+extern struct symbol *lookup_symbol (const char *, const struct block *,
+                                    const namespace_enum, int *,
+                                    struct symtab **);
+
+/* lookup a symbol by name, within a specified block */
+
+extern struct symbol *lookup_block_symbol (const struct block *, const char *,
+                                          const char *,
+                                          const namespace_enum);
+
+/* lookup a [struct, union, enum] by name, within a specified block */
+
+extern struct type *lookup_struct (char *, struct block *);
+
+extern struct type *lookup_union (char *, struct block *);
+
+extern struct type *lookup_enum (char *, struct block *);
+
+/* lookup the function corresponding to the block */
+
+extern struct symbol *block_function (struct block *);
+
+/* from blockframe.c: */
+
+/* lookup the function symbol corresponding to the address */
+
+extern struct symbol *find_pc_function (CORE_ADDR);
+
+/* lookup the function corresponding to the address and section */
+
+extern struct symbol *find_pc_sect_function (CORE_ADDR, asection *);
+
+/* lookup function from address, return name, start addr and end addr */
+
+extern int
+find_pc_partial_function (CORE_ADDR, char **, CORE_ADDR *, CORE_ADDR *);
+
+extern void clear_pc_function_cache (void);
+
+extern int find_pc_sect_partial_function (CORE_ADDR, asection *,
+                                         char **, CORE_ADDR *, CORE_ADDR *);
+
+/* from symtab.c: */
+
+/* lookup partial symbol table by filename */
+
+extern struct partial_symtab *lookup_partial_symtab (const char *);
+
+/* lookup partial symbol table by address */
+
+extern struct partial_symtab *find_pc_psymtab (CORE_ADDR);
+
+/* lookup partial symbol table by address and section */
+
+extern struct partial_symtab *find_pc_sect_psymtab (CORE_ADDR, asection *);
+
+/* lookup full symbol table by address */
+
+extern struct symtab *find_pc_symtab (CORE_ADDR);
+
+/* lookup full symbol table by address and section */
+
+extern struct symtab *find_pc_sect_symtab (CORE_ADDR, asection *);
+
+/* lookup partial symbol by address */
+
+extern struct partial_symbol *find_pc_psymbol (struct partial_symtab *,
+                                              CORE_ADDR);
+
+/* lookup partial symbol by address and section */
+
+extern struct partial_symbol *find_pc_sect_psymbol (struct partial_symtab *,
+                                                   CORE_ADDR, asection *);
+
+extern int find_pc_line_pc_range (CORE_ADDR, CORE_ADDR *, CORE_ADDR *);
+
+extern int contained_in (struct block *, struct block *);
+
+extern void reread_symbols (void);
+
+extern struct type *lookup_transparent_type (const char *);
+
+
+/* Macro for name of symbol to indicate a file compiled with gcc. */
+#ifndef GCC_COMPILED_FLAG_SYMBOL
+#define GCC_COMPILED_FLAG_SYMBOL "gcc_compiled."
+#endif
+
+/* Macro for name of symbol to indicate a file compiled with gcc2. */
+#ifndef GCC2_COMPILED_FLAG_SYMBOL
+#define GCC2_COMPILED_FLAG_SYMBOL "gcc2_compiled."
+#endif
+
+/* Functions for dealing with the minimal symbol table, really a misc
+   address<->symbol mapping for things we don't have debug symbols for.  */
+
+extern void prim_record_minimal_symbol (const char *, CORE_ADDR,
+                                       enum minimal_symbol_type,
+                                       struct objfile *);
+
+extern struct minimal_symbol *prim_record_minimal_symbol_and_info
+  (const char *, CORE_ADDR,
+   enum minimal_symbol_type,
+   char *info, int section, asection * bfd_section, struct objfile *);
+
+extern unsigned int msymbol_hash_iw (const char *);
+
+extern unsigned int msymbol_hash (const char *);
+
+extern void
+add_minsym_to_hash_table (struct minimal_symbol *sym,
+                         struct minimal_symbol **table);
+
+extern struct minimal_symbol *lookup_minimal_symbol (const char *,
+                                                    const char *,
+                                                    struct objfile *);
+
+extern struct minimal_symbol *lookup_minimal_symbol_text (const char *,
+                                                         const char *,
+                                                         struct objfile *);
+
+struct minimal_symbol *lookup_minimal_symbol_solib_trampoline (const char *,
+                                                              const char *,
+                                                              struct objfile
+                                                              *);
+
+extern struct minimal_symbol *lookup_minimal_symbol_by_pc (CORE_ADDR);
+
+extern struct minimal_symbol *lookup_minimal_symbol_by_pc_section (CORE_ADDR,
+                                                                  asection
+                                                                  *);
+
+extern struct minimal_symbol
+  *lookup_solib_trampoline_symbol_by_pc (CORE_ADDR);
+
+extern CORE_ADDR find_solib_trampoline_target (CORE_ADDR);
+
+extern void init_minimal_symbol_collection (void);
+
+extern struct cleanup *make_cleanup_discard_minimal_symbols (void);
+
+extern void install_minimal_symbols (struct objfile *);
+
+/* Sort all the minimal symbols in OBJFILE.  */
+
+extern void msymbols_sort (struct objfile *objfile);
+
+struct symtab_and_line
+{
+  struct symtab *symtab;
+  asection *section;
+  /* Line number.  Line numbers start at 1 and proceed through symtab->nlines.
+     0 is never a valid line number; it is used to indicate that line number
+     information is not available.  */
+  int line;
+
+  CORE_ADDR pc;
+  CORE_ADDR end;
+};
+
+#define INIT_SAL(sal) { \
+  (sal)->symtab  = 0;   \
+  (sal)->section = 0;   \
+  (sal)->line    = 0;   \
+  (sal)->pc      = 0;   \
+  (sal)->end     = 0;   \
+}
+
+struct symtabs_and_lines
+{
+  struct symtab_and_line *sals;
+  int nelts;
+};
+\f
+
+
+/* Some types and macros needed for exception catchpoints.
+   Can't put these in target.h because symtab_and_line isn't
+   known there. This file will be included by breakpoint.c,
+   hppa-tdep.c, etc. */
+
+/* Enums for exception-handling support */
+enum exception_event_kind
+{
+  EX_EVENT_THROW,
+  EX_EVENT_CATCH
+};
+
+/* Type for returning info about an exception */
+struct exception_event_record
+{
+  enum exception_event_kind kind;
+  struct symtab_and_line throw_sal;
+  struct symtab_and_line catch_sal;
+  /* This may need to be extended in the future, if
+     some platforms allow reporting more information,
+     such as point of rethrow, type of exception object,
+     type expected by catch clause, etc. */
+};
+
+#define CURRENT_EXCEPTION_KIND       (current_exception_event->kind)
+#define CURRENT_EXCEPTION_CATCH_SAL  (current_exception_event->catch_sal)
+#define CURRENT_EXCEPTION_CATCH_LINE (current_exception_event->catch_sal.line)
+#define CURRENT_EXCEPTION_CATCH_FILE (current_exception_event->catch_sal.symtab->filename)
+#define CURRENT_EXCEPTION_CATCH_PC   (current_exception_event->catch_sal.pc)
+#define CURRENT_EXCEPTION_THROW_SAL  (current_exception_event->throw_sal)
+#define CURRENT_EXCEPTION_THROW_LINE (current_exception_event->throw_sal.line)
+#define CURRENT_EXCEPTION_THROW_FILE (current_exception_event->throw_sal.symtab->filename)
+#define CURRENT_EXCEPTION_THROW_PC   (current_exception_event->throw_sal.pc)
+\f
+
+/* Given a pc value, return line number it is in.  Second arg nonzero means
+   if pc is on the boundary use the previous statement's line number.  */
+
+extern struct symtab_and_line find_pc_line (CORE_ADDR, int);
+
+/* Same function, but specify a section as well as an address */
+
+extern struct symtab_and_line find_pc_sect_line (CORE_ADDR, asection *, int);
+
+/* Given an address, return the nearest symbol at or below it in memory.
+   Optionally return the symtab it's from through 2nd arg, and the
+   address in inferior memory of the symbol through 3rd arg.  */
+
+extern struct symbol *find_addr_symbol (CORE_ADDR, struct symtab **,
+                                       CORE_ADDR *);
+
+/* Given a symtab and line number, return the pc there.  */
+
+extern int find_line_pc (struct symtab *, int, CORE_ADDR *);
+
+extern int
+find_line_pc_range (struct symtab_and_line, CORE_ADDR *, CORE_ADDR *);
+
+extern void resolve_sal_pc (struct symtab_and_line *);
+
+/* Given a string, return the line specified by it.  For commands like "list"
+   and "breakpoint".  */
+
+extern struct symtabs_and_lines decode_line_spec (char *, int);
+
+extern struct symtabs_and_lines decode_line_spec_1 (char *, int);
+
+/* Symmisc.c */
+
+void maintenance_print_symbols (char *, int);
+
+void maintenance_print_psymbols (char *, int);
+
+void maintenance_print_msymbols (char *, int);
+
+void maintenance_print_objfiles (char *, int);
+
+void maintenance_check_symtabs (char *, int);
+
+/* maint.c */
+
+void maintenance_print_statistics (char *, int);
+
+extern void free_symtab (struct symtab *);
+
+/* Symbol-reading stuff in symfile.c and solib.c.  */
+
+extern struct symtab *psymtab_to_symtab (struct partial_symtab *);
+
+extern void clear_solib (void);
+
+/* source.c */
+
+extern int identify_source_line (struct symtab *, int, int, CORE_ADDR);
+
+extern void print_source_lines (struct symtab *, int, int, int);
+
+extern void forget_cached_source_info (void);
+
+extern void select_source_symtab (struct symtab *);
+
+extern char **make_symbol_completion_list (char *, char *);
+
+extern char **make_file_symbol_completion_list (char *, char *, char *);
+
+extern struct symbol **make_symbol_overload_list (struct symbol *);
+
+extern char **make_source_files_completion_list (char *, char *);
+
+/* symtab.c */
+
+extern struct partial_symtab *find_main_psymtab (void);
+
+extern struct symtab *find_line_symtab (struct symtab *, int, int *, int *);
+
+extern struct symtab_and_line find_function_start_sal (struct symbol *sym,
+                                                      int);
+
+/* blockframe.c */
+
+extern struct blockvector *blockvector_for_pc (CORE_ADDR, int *);
+
+extern struct blockvector *blockvector_for_pc_sect (CORE_ADDR, asection *,
+                                                   int *, struct symtab *);
+
+/* symfile.c */
+
+extern void clear_symtab_users (void);
+
+extern enum language deduce_language_from_filename (char *);
+
+/* symtab.c */
+
+extern int in_prologue (CORE_ADDR pc, CORE_ADDR func_start);
+
+extern struct symbol *fixup_symbol_section (struct symbol *,
+                                           struct objfile *);
+
+extern struct partial_symbol *fixup_psymbol_section (struct partial_symbol
+                                                    *psym,
+                                                    struct objfile *objfile);
+
+/* Symbol searching */
+
+/* When using search_symbols, a list of the following structs is returned.
+   Callers must free the search list using free_search_symbols! */
+struct symbol_search
+{
+  /* The block in which the match was found. Could be, for example,
+     STATIC_BLOCK or GLOBAL_BLOCK. */
+  int block;
+
+  /* Information describing what was found.
+
+     If symtab abd symbol are NOT NULL, then information was found
+     for this match. */
+  struct symtab *symtab;
+  struct symbol *symbol;
+
+  /* If msymbol is non-null, then a match was made on something for
+     which only minimal_symbols exist. */
+  struct minimal_symbol *msymbol;
+
+  /* A link to the next match, or NULL for the end. */
+  struct symbol_search *next;
+};
+
+extern void search_symbols (char *, namespace_enum, int, char **,
+                           struct symbol_search **);
+extern void free_search_symbols (struct symbol_search *);
+extern struct cleanup *make_cleanup_free_search_symbols (struct symbol_search
+                                                        *);
+
+/* The name of the ``main'' function.
+   FIXME: cagney/2001-03-20: Can't make main_name() const since some
+   of the calling code currently assumes that the string isn't
+   const. */
+extern void set_main_name (const char *name);
+extern /*const */ char *main_name (void);
+
+#endif /* !defined(SYMTAB_H) */
diff --git a/gdb/xcoffread.c b/gdb/xcoffread.c
new file mode 100644 (file)
index 0000000..0e85125
--- /dev/null
@@ -0,0 +1,3049 @@
+/* Read AIX xcoff symbol tables and convert to internal format, for GDB.
+   Copyright 1986, 1987, 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1995,
+   1996, 1997, 1998, 1999, 2000, 2001
+   Free Software Foundation, Inc.
+   Derived from coffread.c, dbxread.c, and a lot of hacking.
+   Contributed by IBM Corporation.
+
+   This file is part of GDB.
+
+   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.  */
+
+#include "defs.h"
+#include "bfd.h"
+
+#include <sys/types.h>
+#include <fcntl.h>
+#include <ctype.h>
+#include "gdb_string.h"
+
+#include <sys/param.h>
+#ifndef        NO_SYS_FILE
+#include <sys/file.h>
+#endif
+#include "gdb_stat.h"
+
+#include "coff/internal.h"
+#include "libcoff.h"           /* FIXME, internal data from BFD */
+#include "coff/xcoff.h"
+#include "libxcoff.h"
+#include "coff/rs6000.h"
+
+#include "symtab.h"
+#include "gdbtypes.h"
+#include "symfile.h"
+#include "objfiles.h"
+#include "buildsym.h"
+#include "stabsread.h"
+#include "expression.h"
+#include "complaints.h"
+
+#include "gdb-stabs.h"
+
+/* For interface with stabsread.c.  */
+#include "aout/stab_gnu.h"
+
+\f
+/* We put a pointer to this structure in the read_symtab_private field
+   of the psymtab.  */
+
+struct symloc
+  {
+
+    /* First symbol number for this file.  */
+
+    int first_symnum;
+
+    /* Number of symbols in the section of the symbol table devoted to
+       this file's symbols (actually, the section bracketed may contain
+       more than just this file's symbols).  If numsyms is 0, the only
+       reason for this thing's existence is the dependency list.  Nothing
+       else will happen when it is read in.  */
+
+    int numsyms;
+
+    /* Position of the start of the line number information for this psymtab.  */
+    unsigned int lineno_off;
+  };
+
+/* Remember what we deduced to be the source language of this psymtab. */
+
+static enum language psymtab_language = language_unknown;
+\f
+
+/* Simplified internal version of coff symbol table information */
+
+struct coff_symbol
+  {
+    char *c_name;
+    int c_symnum;              /* symbol number of this entry */
+    int c_naux;                        /* 0 if syment only, 1 if syment + auxent */
+    long c_value;
+    unsigned char c_sclass;
+    int c_secnum;
+    unsigned int c_type;
+  };
+
+/* last function's saved coff symbol `cs' */
+
+static struct coff_symbol fcn_cs_saved;
+
+static bfd *symfile_bfd;
+
+/* Core address of start and end of text of current source file.
+   This is calculated from the first function seen after a C_FILE
+   symbol. */
+
+
+static CORE_ADDR cur_src_end_addr;
+
+/* Core address of the end of the first object file.  */
+
+static CORE_ADDR first_object_file_end;
+
+/* initial symbol-table-debug-string vector length */
+
+#define        INITIAL_STABVECTOR_LENGTH       40
+
+/* Nonzero if within a function (so symbols should be local,
+   if nothing says specifically).  */
+
+int within_function;
+
+/* Size of a COFF symbol.  I think it is always 18, so I'm not sure
+   there is any reason not to just use a #define, but might as well
+   ask BFD for the size and store it here, I guess.  */
+
+static unsigned local_symesz;
+
+struct coff_symfile_info
+  {
+    file_ptr min_lineno_offset;        /* Where in file lowest line#s are */
+    file_ptr max_lineno_offset;        /* 1+last byte of line#s in file */
+
+    /* Pointer to the string table.  */
+    char *strtbl;
+
+    /* Pointer to debug section.  */
+    char *debugsec;
+
+    /* Pointer to the a.out symbol table.  */
+    char *symtbl;
+
+    /* Number of symbols in symtbl.  */
+    int symtbl_num_syms;
+
+    /* Offset in data section to TOC anchor.  */
+    CORE_ADDR toc_offset;
+  };
+
+static struct complaint storclass_complaint =
+{"Unexpected storage class: %d", 0, 0};
+
+static struct complaint bf_notfound_complaint =
+{"line numbers off, `.bf' symbol not found", 0, 0};
+
+static struct complaint ef_complaint =
+{"Mismatched .ef symbol ignored starting at symnum %d", 0, 0};
+
+static struct complaint eb_complaint =
+{"Mismatched .eb symbol ignored starting at symnum %d", 0, 0};
+
+static void xcoff_initial_scan (struct objfile *, int);
+
+static void scan_xcoff_symtab (struct objfile *);
+
+static char *xcoff_next_symbol_text (struct objfile *);
+
+static void record_include_begin (struct coff_symbol *);
+
+static void
+enter_line_range (struct subfile *, unsigned, unsigned,
+                 CORE_ADDR, CORE_ADDR, unsigned *);
+
+static void init_stringtab (bfd *, file_ptr, struct objfile *);
+
+static void xcoff_symfile_init (struct objfile *);
+
+static void xcoff_new_init (struct objfile *);
+
+static void xcoff_symfile_finish (struct objfile *);
+
+static void
+xcoff_symfile_offsets (struct objfile *, struct section_addr_info *addrs);
+
+static void find_linenos (bfd *, sec_ptr, PTR);
+
+static char *coff_getfilename (union internal_auxent *, struct objfile *);
+
+static void read_symbol (struct internal_syment *, int);
+
+static int read_symbol_lineno (int);
+
+static CORE_ADDR read_symbol_nvalue (int);
+
+static struct symbol *process_xcoff_symbol (struct coff_symbol *,
+                                           struct objfile *);
+
+static void read_xcoff_symtab (struct partial_symtab *);
+
+#if 0
+static void add_stab_to_list (char *, struct pending_stabs **);
+#endif
+
+static int compare_lte (const void *, const void *);
+
+static struct linetable *arrange_linetable (struct linetable *);
+
+static void record_include_end (struct coff_symbol *);
+
+static void process_linenos (CORE_ADDR, CORE_ADDR);
+\f
+
+/* Translate from a COFF section number (target_index) to a SECT_OFF_*
+   code.  */
+static int secnum_to_section (int, struct objfile *);
+static asection *secnum_to_bfd_section (int, struct objfile *);
+
+struct find_targ_sec_arg
+  {
+    int targ_index;
+    int *resultp;
+    asection **bfd_sect;
+    struct objfile *objfile;
+  };
+
+static void find_targ_sec (bfd *, asection *, void *);
+
+static void
+find_targ_sec (bfd *abfd, asection *sect, PTR obj)
+{
+  struct find_targ_sec_arg *args = (struct find_targ_sec_arg *) obj;
+  struct objfile *objfile = args->objfile;
+  if (sect->target_index == args->targ_index)
+    {
+      /* This is the section.  Figure out what SECT_OFF_* code it is.  */
+      if (bfd_get_section_flags (abfd, sect) & SEC_CODE)
+       *args->resultp = SECT_OFF_TEXT (objfile);
+      else if (bfd_get_section_flags (abfd, sect) & SEC_LOAD)
+       *args->resultp = SECT_OFF_DATA (objfile);
+      else
+       *args->resultp = sect->index;
+      *args->bfd_sect = sect;
+    }
+}
+
+/* Return the section number (SECT_OFF_*) that CS points to.  */
+static int
+secnum_to_section (int secnum, struct objfile *objfile)
+{
+  int off = SECT_OFF_TEXT (objfile);
+  asection *sect = NULL;
+  struct find_targ_sec_arg args;
+  args.targ_index = secnum;
+  args.resultp = &off;
+  args.bfd_sect = &sect;
+  args.objfile = objfile;
+  bfd_map_over_sections (objfile->obfd, find_targ_sec, &args);
+  return off;
+}
+
+/* Return the BFD section that CS points to.  */
+static asection *
+secnum_to_bfd_section (int secnum, struct objfile *objfile)
+{
+  int off = SECT_OFF_TEXT (objfile);
+  asection *sect = NULL;
+  struct find_targ_sec_arg args;
+  args.targ_index = secnum;
+  args.resultp = &off;
+  args.bfd_sect = &sect;
+  args.objfile = objfile;
+  bfd_map_over_sections (objfile->obfd, find_targ_sec, &args);
+  return sect;
+}
+\f
+/* add a given stab string into given stab vector. */
+
+#if 0
+
+static void
+add_stab_to_list (char *stabname, struct pending_stabs **stabvector)
+{
+  if (*stabvector == NULL)
+    {
+      *stabvector = (struct pending_stabs *)
+       xmalloc (sizeof (struct pending_stabs) +
+                INITIAL_STABVECTOR_LENGTH * sizeof (char *));
+      (*stabvector)->count = 0;
+      (*stabvector)->length = INITIAL_STABVECTOR_LENGTH;
+    }
+  else if ((*stabvector)->count >= (*stabvector)->length)
+    {
+      (*stabvector)->length += INITIAL_STABVECTOR_LENGTH;
+      *stabvector = (struct pending_stabs *)
+       xrealloc ((char *) *stabvector, sizeof (struct pending_stabs) +
+                   (*stabvector)->length * sizeof (char *));
+    }
+  (*stabvector)->stab[(*stabvector)->count++] = stabname;
+}
+
+#endif
+\f/* *INDENT-OFF* */
+/* Linenos are processed on a file-by-file basis.
+
+   Two reasons:
+
+   1) xlc (IBM's native c compiler) postpones static function code
+   emission to the end of a compilation unit. This way it can
+   determine if those functions (statics) are needed or not, and
+   can do some garbage collection (I think). This makes line
+   numbers and corresponding addresses unordered, and we end up
+   with a line table like:
+
+
+   lineno       addr
+   foo()          10    0x100
+   20   0x200
+   30   0x300
+
+   foo3()         70    0x400
+   80   0x500
+   90   0x600
+
+   static foo2()
+   40   0x700
+   50   0x800
+   60   0x900           
+
+   and that breaks gdb's binary search on line numbers, if the
+   above table is not sorted on line numbers. And that sort
+   should be on function based, since gcc can emit line numbers
+   like:
+
+   10   0x100   - for the init/test part of a for stmt.
+   20   0x200
+   30   0x300
+   10   0x400   - for the increment part of a for stmt.
+
+   arrange_linetable() will do this sorting.            
+
+   2)   aix symbol table might look like:
+
+   c_file               // beginning of a new file
+   .bi          // beginning of include file
+   .ei          // end of include file
+   .bi
+   .ei
+
+   basically, .bi/.ei pairs do not necessarily encapsulate
+   their scope. They need to be recorded, and processed later
+   on when we come the end of the compilation unit.
+   Include table (inclTable) and process_linenos() handle
+   that.  */
+/* *INDENT-ON* */
+
+
+
+/* compare line table entry addresses. */
+
+static int
+compare_lte (const void *lte1p, const void *lte2p)
+{
+  struct linetable_entry *lte1 = (struct linetable_entry *) lte1p;
+  struct linetable_entry *lte2 = (struct linetable_entry *) lte2p;
+  return lte1->pc - lte2->pc;
+}
+
+/* Given a line table with function entries are marked, arrange its functions
+   in ascending order and strip off function entry markers and return it in
+   a newly created table. If the old one is good enough, return the old one. */
+/* FIXME: I think all this stuff can be replaced by just passing
+   sort_linevec = 1 to end_symtab.  */
+
+static struct linetable *
+arrange_linetable (struct linetable *oldLineTb)
+{
+  int ii, jj, newline,         /* new line count */
+    function_count;            /* # of functions */
+
+  struct linetable_entry *fentry;      /* function entry vector */
+  int fentry_size;             /* # of function entries */
+  struct linetable *newLineTb; /* new line table */
+
+#define NUM_OF_FUNCTIONS 20
+
+  fentry_size = NUM_OF_FUNCTIONS;
+  fentry = (struct linetable_entry *)
+    xmalloc (fentry_size * sizeof (struct linetable_entry));
+
+  for (function_count = 0, ii = 0; ii < oldLineTb->nitems; ++ii)
+    {
+
+      if (oldLineTb->item[ii].line == 0)
+       {                       /* function entry found. */
+
+         if (function_count >= fentry_size)
+           {                   /* make sure you have room. */
+             fentry_size *= 2;
+             fentry = (struct linetable_entry *)
+               xrealloc (fentry, fentry_size * sizeof (struct linetable_entry));
+           }
+         fentry[function_count].line = ii;
+         fentry[function_count].pc = oldLineTb->item[ii].pc;
+         ++function_count;
+       }
+    }
+
+  if (function_count == 0)
+    {
+      xfree (fentry);
+      return oldLineTb;
+    }
+  else if (function_count > 1)
+    qsort (fentry, function_count, sizeof (struct linetable_entry), compare_lte);
+
+  /* allocate a new line table. */
+  newLineTb = (struct linetable *)
+    xmalloc
+    (sizeof (struct linetable) +
+    (oldLineTb->nitems - function_count) * sizeof (struct linetable_entry));
+
+  /* if line table does not start with a function beginning, copy up until
+     a function begin. */
+
+  newline = 0;
+  if (oldLineTb->item[0].line != 0)
+    for (newline = 0;
+    newline < oldLineTb->nitems && oldLineTb->item[newline].line; ++newline)
+      newLineTb->item[newline] = oldLineTb->item[newline];
+
+  /* Now copy function lines one by one. */
+
+  for (ii = 0; ii < function_count; ++ii)
+    {
+      for (jj = fentry[ii].line + 1;
+          jj < oldLineTb->nitems && oldLineTb->item[jj].line != 0;
+          ++jj, ++newline)
+       newLineTb->item[newline] = oldLineTb->item[jj];
+    }
+  xfree (fentry);
+  newLineTb->nitems = oldLineTb->nitems - function_count;
+  return newLineTb;
+}
+
+/* include file support: C_BINCL/C_EINCL pairs will be kept in the 
+   following `IncludeChain'. At the end of each symtab (end_symtab),
+   we will determine if we should create additional symtab's to
+   represent if (the include files. */
+
+
+typedef struct _inclTable
+{
+  char *name;                  /* include filename */
+
+  /* Offsets to the line table.  end points to the last entry which is
+     part of this include file.  */
+  int begin, end;
+
+  struct subfile *subfile;
+  unsigned funStartLine;       /* start line # of its function */
+}
+InclTable;
+
+#define        INITIAL_INCLUDE_TABLE_LENGTH    20
+static InclTable *inclTable;   /* global include table */
+static int inclIndx;           /* last entry to table */
+static int inclLength;         /* table length */
+static int inclDepth;          /* nested include depth */
+
+static void allocate_include_entry (void);
+
+static void
+record_include_begin (struct coff_symbol *cs)
+{
+  if (inclDepth)
+    {
+      /* In xcoff, we assume include files cannot be nested (not in .c files
+         of course, but in corresponding .s files.).  */
+
+      /* This can happen with old versions of GCC.
+         GCC 2.3.3-930426 does not exhibit this on a test case which
+         a user said produced the message for him.  */
+      static struct complaint msg =
+      {"Nested C_BINCL symbols", 0, 0};
+      complain (&msg);
+    }
+  ++inclDepth;
+
+  allocate_include_entry ();
+
+  inclTable[inclIndx].name = cs->c_name;
+  inclTable[inclIndx].begin = cs->c_value;
+}
+
+static void
+record_include_end (struct coff_symbol *cs)
+{
+  InclTable *pTbl;
+
+  if (inclDepth == 0)
+    {
+      static struct complaint msg =
+      {"Mismatched C_BINCL/C_EINCL pair", 0, 0};
+      complain (&msg);
+    }
+
+  allocate_include_entry ();
+
+  pTbl = &inclTable[inclIndx];
+  pTbl->end = cs->c_value;
+
+  --inclDepth;
+  ++inclIndx;
+}
+
+static void
+allocate_include_entry (void)
+{
+  if (inclTable == NULL)
+    {
+      inclTable = (InclTable *)
+       xmalloc (sizeof (InclTable) * INITIAL_INCLUDE_TABLE_LENGTH);
+      memset (inclTable,
+             '\0', sizeof (InclTable) * INITIAL_INCLUDE_TABLE_LENGTH);
+      inclLength = INITIAL_INCLUDE_TABLE_LENGTH;
+      inclIndx = 0;
+    }
+  else if (inclIndx >= inclLength)
+    {
+      inclLength += INITIAL_INCLUDE_TABLE_LENGTH;
+      inclTable = (InclTable *)
+       xrealloc (inclTable, sizeof (InclTable) * inclLength);
+      memset (inclTable + inclLength - INITIAL_INCLUDE_TABLE_LENGTH,
+             '\0', sizeof (InclTable) * INITIAL_INCLUDE_TABLE_LENGTH);
+    }
+}
+
+/* Global variable to pass the psymtab down to all the routines involved
+   in psymtab to symtab processing.  */
+static struct partial_symtab *this_symtab_psymtab;
+
+/* given the start and end addresses of a compilation unit (or a csect,
+   at times) process its lines and create appropriate line vectors. */
+
+static void
+process_linenos (CORE_ADDR start, CORE_ADDR end)
+{
+  int offset, ii;
+  file_ptr max_offset =
+  ((struct coff_symfile_info *) this_symtab_psymtab->objfile->sym_private)
+  ->max_lineno_offset;
+
+  /* subfile structure for the main compilation unit.  */
+  struct subfile main_subfile;
+
+  /* In the main source file, any time we see a function entry, we
+     reset this variable to function's absolute starting line number.
+     All the following line numbers in the function are relative to
+     this, and we record absolute line numbers in record_line().  */
+
+  unsigned int main_source_baseline = 0;
+
+  unsigned *firstLine;
+
+  offset =
+    ((struct symloc *) this_symtab_psymtab->read_symtab_private)->lineno_off;
+  if (offset == 0)
+    goto return_after_cleanup;
+
+  memset (&main_subfile, '\0', sizeof (main_subfile));
+
+  if (inclIndx == 0)
+    /* All source lines were in the main source file. None in include files. */
+
+    enter_line_range (&main_subfile, offset, 0, start, end,
+                     &main_source_baseline);
+
+  else
+    {
+      /* There was source with line numbers in include files.  */
+
+      int linesz =
+       coff_data (this_symtab_psymtab->objfile->obfd)->local_linesz;
+      main_source_baseline = 0;
+
+      for (ii = 0; ii < inclIndx; ++ii)
+       {
+         struct subfile *tmpSubfile;
+
+         /* If there is main file source before include file, enter it.  */
+         if (offset < inclTable[ii].begin)
+           {
+             enter_line_range
+               (&main_subfile, offset, inclTable[ii].begin - linesz,
+                start, 0, &main_source_baseline);
+           }
+
+         /* Have a new subfile for the include file.  */
+
+         tmpSubfile = inclTable[ii].subfile =
+           (struct subfile *) xmalloc (sizeof (struct subfile));
+
+         memset (tmpSubfile, '\0', sizeof (struct subfile));
+         firstLine = &(inclTable[ii].funStartLine);
+
+         /* Enter include file's lines now.  */
+         enter_line_range (tmpSubfile, inclTable[ii].begin,
+                           inclTable[ii].end, start, 0, firstLine);
+
+         if (offset <= inclTable[ii].end)
+           offset = inclTable[ii].end + linesz;
+       }
+
+      /* All the include files' line have been processed at this point.  Now,
+         enter remaining lines of the main file, if any left.  */
+      if (offset < max_offset + 1 - linesz)
+       {
+         enter_line_range (&main_subfile, offset, 0, start, end,
+                           &main_source_baseline);
+       }
+    }
+
+  /* Process main file's line numbers.  */
+  if (main_subfile.line_vector)
+    {
+      struct linetable *lineTb, *lv;
+
+      lv = main_subfile.line_vector;
+
+      /* Line numbers are not necessarily ordered. xlc compilation will
+         put static function to the end. */
+
+      lineTb = arrange_linetable (lv);
+      if (lv == lineTb)
+       {
+         current_subfile->line_vector = (struct linetable *)
+           xrealloc (lv, (sizeof (struct linetable)
+                          + lv->nitems * sizeof (struct linetable_entry)));
+       }
+      else
+       {
+         xfree (lv);
+         current_subfile->line_vector = lineTb;
+       }
+
+      current_subfile->line_vector_length =
+       current_subfile->line_vector->nitems;
+    }
+
+  /* Now, process included files' line numbers.  */
+
+  for (ii = 0; ii < inclIndx; ++ii)
+    {
+      if ((inclTable[ii].subfile)->line_vector)                /* Useless if!!! FIXMEmgo */
+       {
+         struct linetable *lineTb, *lv;
+
+         lv = (inclTable[ii].subfile)->line_vector;
+
+         /* Line numbers are not necessarily ordered. xlc compilation will
+            put static function to the end. */
+
+         lineTb = arrange_linetable (lv);
+
+         push_subfile ();
+
+         /* For the same include file, we might want to have more than one
+            subfile.  This happens if we have something like:
+
+            ......
+            #include "foo.h"
+            ......
+            #include "foo.h"
+            ......
+
+            while foo.h including code in it. (stupid but possible)
+            Since start_subfile() looks at the name and uses an
+            existing one if finds, we need to provide a fake name and
+            fool it.  */
+
+#if 0
+         start_subfile (inclTable[ii].name, (char *) 0);
+#else
+         {
+           /* Pick a fake name that will produce the same results as this
+              one when passed to deduce_language_from_filename.  Kludge on
+              top of kludge.  */
+           char *fakename = strrchr (inclTable[ii].name, '.');
+           if (fakename == NULL)
+             fakename = " ?";
+           start_subfile (fakename, (char *) 0);
+           xfree (current_subfile->name);
+         }
+         current_subfile->name = xstrdup (inclTable[ii].name);
+#endif
+
+         if (lv == lineTb)
+           {
+             current_subfile->line_vector =
+               (struct linetable *) xrealloc
+               (lv, (sizeof (struct linetable)
+                     + lv->nitems * sizeof (struct linetable_entry)));
+
+           }
+         else
+           {
+             xfree (lv);
+             current_subfile->line_vector = lineTb;
+           }
+
+         current_subfile->line_vector_length =
+           current_subfile->line_vector->nitems;
+         start_subfile (pop_subfile (), (char *) 0);
+       }
+    }
+
+return_after_cleanup:
+
+  /* We don't want to keep alloc/free'ing the global include file table.  */
+  inclIndx = 0;
+
+  /* Start with a fresh subfile structure for the next file.  */
+  memset (&main_subfile, '\0', sizeof (struct subfile));
+}
+
+void
+aix_process_linenos (void)
+{
+  /* process line numbers and enter them into line vector */
+  process_linenos (last_source_start_addr, cur_src_end_addr);
+}
+
+
+/* Enter a given range of lines into the line vector.
+   can be called in the following two ways:
+   enter_line_range (subfile, beginoffset, endoffset, startaddr, 0, firstLine)  or
+   enter_line_range (subfile, beginoffset, 0, startaddr, endaddr, firstLine)
+
+   endoffset points to the last line table entry that we should pay
+   attention to.  */
+
+static void
+enter_line_range (struct subfile *subfile, unsigned beginoffset, unsigned endoffset,   /* offsets to line table */
+                 CORE_ADDR startaddr,  /* offsets to line table */
+                 CORE_ADDR endaddr, unsigned *firstLine)
+{
+  unsigned int curoffset;
+  CORE_ADDR addr;
+  void *ext_lnno;
+  struct internal_lineno int_lnno;
+  unsigned int limit_offset;
+  bfd *abfd;
+  int linesz;
+
+  if (endoffset == 0 && startaddr == 0 && endaddr == 0)
+    return;
+  curoffset = beginoffset;
+  limit_offset =
+    ((struct coff_symfile_info *) this_symtab_psymtab->objfile->sym_private)
+    ->max_lineno_offset;
+
+  if (endoffset != 0)
+    {
+      if (endoffset >= limit_offset)
+       {
+         static struct complaint msg =
+         {"Bad line table offset in C_EINCL directive", 0, 0};
+         complain (&msg);
+         return;
+       }
+      limit_offset = endoffset;
+    }
+  else
+    limit_offset -= 1;
+
+  abfd = this_symtab_psymtab->objfile->obfd;
+  linesz = coff_data (abfd)->local_linesz;
+  ext_lnno = alloca (linesz);
+
+  while (curoffset <= limit_offset)
+    {
+      bfd_seek (abfd, curoffset, SEEK_SET);
+      bfd_bread (ext_lnno, linesz, abfd);
+      bfd_coff_swap_lineno_in (abfd, ext_lnno, &int_lnno);
+
+      /* Find the address this line represents.  */
+      addr = (int_lnno.l_lnno
+             ? int_lnno.l_addr.l_paddr
+             : read_symbol_nvalue (int_lnno.l_addr.l_symndx));
+      addr += ANOFFSET (this_symtab_psymtab->objfile->section_offsets,
+                       SECT_OFF_TEXT (this_symtab_psymtab->objfile));
+
+      if (addr < startaddr || (endaddr && addr >= endaddr))
+       return;
+
+      if (int_lnno.l_lnno == 0)
+       {
+         *firstLine = read_symbol_lineno (int_lnno.l_addr.l_symndx);
+         record_line (subfile, 0, addr);
+         --(*firstLine);
+       }
+      else
+       record_line (subfile, *firstLine + int_lnno.l_lnno, addr);
+      curoffset += linesz;
+    }
+}
+
+
+/* Save the vital information for use when closing off the current file.
+   NAME is the file name the symbols came from, START_ADDR is the first
+   text address for the file, and SIZE is the number of bytes of text.  */
+
+#define complete_symtab(name, start_addr) {    \
+  last_source_file = savestring (name, strlen (name)); \
+  last_source_start_addr = start_addr;                 \
+}
+
+
+/* Refill the symbol table input buffer
+   and set the variables that control fetching entries from it.
+   Reports an error if no data available.
+   This function can read past the end of the symbol table
+   (into the string table) but this does no harm.  */
+
+/* Reading symbol table has to be fast! Keep the followings as macros, rather
+   than functions. */
+
+#define        RECORD_MINIMAL_SYMBOL(NAME, ADDR, TYPE, SECTION, OBJFILE) \
+{                                              \
+  char *namestr;                               \
+  namestr = (NAME); \
+  if (namestr[0] == '.') ++namestr; \
+  prim_record_minimal_symbol_and_info (namestr, (ADDR), (TYPE), \
+                                      (char *)NULL, (SECTION), (asection *)NULL, (OBJFILE)); \
+  misc_func_recorded = 1;                                      \
+}
+
+
+/* xcoff has static blocks marked in `.bs', `.es' pairs. They cannot be
+   nested. At any given time, a symbol can only be in one static block.
+   This is the base address of current static block, zero if non exists. */
+
+static int static_block_base = 0;
+
+/* Section number for the current static block.  */
+
+static int static_block_section = -1;
+
+/* true if space for symbol name has been allocated. */
+
+static int symname_alloced = 0;
+
+/* Next symbol to read.  Pointer into raw seething symbol table.  */
+
+static char *raw_symbol;
+
+/* This is the function which stabsread.c calls to get symbol
+   continuations.  */
+
+static char *
+xcoff_next_symbol_text (struct objfile *objfile)
+{
+  struct internal_syment symbol;
+  static struct complaint msg =
+  {"Unexpected symbol continuation", 0, 0};
+  char *retval;
+  /* FIXME: is this the same as the passed arg? */
+  objfile = this_symtab_psymtab->objfile;
+
+  bfd_coff_swap_sym_in (objfile->obfd, raw_symbol, &symbol);
+  if (symbol.n_zeroes)
+    {
+      complain (&msg);
+
+      /* Return something which points to '\0' and hope the symbol reading
+         code does something reasonable.  */
+      retval = "";
+    }
+  else if (symbol.n_sclass & 0x80)
+    {
+      retval =
+       ((struct coff_symfile_info *) objfile->sym_private)->debugsec
+       + symbol.n_offset;
+      raw_symbol +=
+       coff_data (objfile->obfd)->local_symesz;
+      ++symnum;
+    }
+  else
+    {
+      complain (&msg);
+
+      /* Return something which points to '\0' and hope the symbol reading
+         code does something reasonable.  */
+      retval = "";
+    }
+  return retval;
+}
+
+/* Read symbols for a given partial symbol table.  */
+
+static void
+read_xcoff_symtab (struct partial_symtab *pst)
+{
+  struct objfile *objfile = pst->objfile;
+  bfd *abfd = objfile->obfd;
+  char *raw_auxptr;            /* Pointer to first raw aux entry for sym */
+  char *strtbl = ((struct coff_symfile_info *) objfile->sym_private)->strtbl;
+  char *debugsec =
+  ((struct coff_symfile_info *) objfile->sym_private)->debugsec;
+  char *debugfmt = bfd_xcoff_is_xcoff64 (abfd) ? "XCOFF64" : "XCOFF";
+
+  struct internal_syment symbol[1];
+  union internal_auxent main_aux;
+  struct coff_symbol cs[1];
+  CORE_ADDR file_start_addr = 0;
+  CORE_ADDR file_end_addr = 0;
+
+  int next_file_symnum = -1;
+  unsigned int max_symnum;
+  int just_started = 1;
+  int depth = 0;
+  int fcn_start_addr = 0;
+
+  struct coff_symbol fcn_stab_saved;
+
+  /* fcn_cs_saved is global because process_xcoff_symbol needs it. */
+  union internal_auxent fcn_aux_saved;
+  struct context_stack *new;
+
+  char *filestring = " _start_ ";      /* Name of the current file. */
+
+  char *last_csect_name;       /* last seen csect's name and value */
+  CORE_ADDR last_csect_val;
+  int last_csect_sec;
+
+  this_symtab_psymtab = pst;
+
+  /* Get the appropriate COFF "constants" related to the file we're
+     handling. */
+  local_symesz = coff_data (abfd)->local_symesz;
+
+  last_source_file = NULL;
+  last_csect_name = 0;
+  last_csect_val = 0;
+
+  start_stabs ();
+  start_symtab (filestring, (char *) NULL, file_start_addr);
+  record_debugformat (debugfmt);
+  symnum = ((struct symloc *) pst->read_symtab_private)->first_symnum;
+  max_symnum =
+    symnum + ((struct symloc *) pst->read_symtab_private)->numsyms;
+  first_object_file_end = 0;
+
+  raw_symbol =
+    ((struct coff_symfile_info *) objfile->sym_private)->symtbl
+    + symnum * local_symesz;
+
+  while (symnum < max_symnum)
+    {
+
+      QUIT;                    /* make this command interruptable.  */
+
+      /* READ_ONE_SYMBOL (symbol, cs, symname_alloced); */
+      /* read one symbol into `cs' structure. After processing the
+         whole symbol table, only string table will be kept in memory,
+         symbol table and debug section of xcoff will be freed. Thus
+         we can mark symbols with names in string table as
+         `alloced'. */
+      {
+       int ii;
+
+       /* Swap and align the symbol into a reasonable C structure.  */
+       bfd_coff_swap_sym_in (abfd, raw_symbol, symbol);
+
+       cs->c_symnum = symnum;
+       cs->c_naux = symbol->n_numaux;
+       if (symbol->n_zeroes)
+         {
+           symname_alloced = 0;
+           /* We must use the original, unswapped, name here so the name field
+              pointed to by cs->c_name will persist throughout xcoffread.  If
+              we use the new field, it gets overwritten for each symbol.  */
+           cs->c_name = ((struct external_syment *) raw_symbol)->e.e_name;
+           /* If it's exactly E_SYMNMLEN characters long it isn't
+              '\0'-terminated.  */
+           if (cs->c_name[E_SYMNMLEN - 1] != '\0')
+             {
+               char *p;
+               p = obstack_alloc (&objfile->symbol_obstack, E_SYMNMLEN + 1);
+               strncpy (p, cs->c_name, E_SYMNMLEN);
+               p[E_SYMNMLEN] = '\0';
+               cs->c_name = p;
+               symname_alloced = 1;
+             }
+         }
+       else if (symbol->n_sclass & 0x80)
+         {
+           cs->c_name = debugsec + symbol->n_offset;
+           symname_alloced = 0;
+         }
+       else
+         {
+           /* in string table */
+           cs->c_name = strtbl + (int) symbol->n_offset;
+           symname_alloced = 1;
+         }
+       cs->c_value = symbol->n_value;
+       cs->c_sclass = symbol->n_sclass;
+       cs->c_secnum = symbol->n_scnum;
+       cs->c_type = (unsigned) symbol->n_type;
+
+       raw_symbol += local_symesz;
+       ++symnum;
+
+       /* Save addr of first aux entry.  */
+       raw_auxptr = raw_symbol;
+
+       /* Skip all the auxents associated with this symbol.  */
+       for (ii = symbol->n_numaux; ii; --ii)
+         {
+           raw_symbol += coff_data (abfd)->local_auxesz;
+           ++symnum;
+         }
+      }
+
+      /* if symbol name starts with ".$" or "$", ignore it. */
+      if (cs->c_name[0] == '$'
+         || (cs->c_name[1] == '$' && cs->c_name[0] == '.'))
+       continue;
+
+      if (cs->c_symnum == next_file_symnum && cs->c_sclass != C_FILE)
+       {
+         if (last_source_file)
+           {
+             pst->symtab =
+               end_symtab (cur_src_end_addr, objfile, SECT_OFF_TEXT (objfile));
+             end_stabs ();
+           }
+
+         start_stabs ();
+         start_symtab ("_globals_", (char *) NULL, (CORE_ADDR) 0);
+         record_debugformat (debugfmt);
+         cur_src_end_addr = first_object_file_end;
+         /* done with all files, everything from here on is globals */
+       }
+
+      if ((cs->c_sclass == C_EXT || cs->c_sclass == C_HIDEXT)
+         && cs->c_naux == 1)
+       {
+         /* Dealing with a symbol with a csect entry.  */
+
+#define        CSECT(PP) ((PP)->x_csect)
+#define        CSECT_LEN(PP) (CSECT(PP).x_scnlen.l)
+#define        CSECT_ALIGN(PP) (SMTYP_ALIGN(CSECT(PP).x_smtyp))
+#define        CSECT_SMTYP(PP) (SMTYP_SMTYP(CSECT(PP).x_smtyp))
+#define        CSECT_SCLAS(PP) (CSECT(PP).x_smclas)
+
+         /* Convert the auxent to something we can access.  */
+         bfd_coff_swap_aux_in (abfd, raw_auxptr, cs->c_type, cs->c_sclass,
+                               0, cs->c_naux, &main_aux);
+
+         switch (CSECT_SMTYP (&main_aux))
+           {
+
+           case XTY_ER:
+             /* Ignore all external references.  */
+             continue;
+
+           case XTY_SD:
+             /* A section description.  */
+             {
+               switch (CSECT_SCLAS (&main_aux))
+                 {
+
+                 case XMC_PR:
+                   {
+
+                     /* A program csect is seen.  We have to allocate one
+                        symbol table for each program csect.  Normally gdb
+                        prefers one symtab for each source file.  In case
+                        of AIX, one source file might include more than one
+                        [PR] csect, and they don't have to be adjacent in
+                        terms of the space they occupy in memory. Thus, one
+                        single source file might get fragmented in the
+                        memory and gdb's file start and end address
+                        approach does not work!  GCC (and I think xlc) seem
+                        to put all the code in the unnamed program csect.  */
+
+                     if (last_csect_name)
+                       {
+                         complete_symtab (filestring, file_start_addr);
+                         cur_src_end_addr = file_end_addr;
+                         end_symtab (file_end_addr, objfile, SECT_OFF_TEXT (objfile));
+                         end_stabs ();
+                         start_stabs ();
+                         /* Give all csects for this source file the same
+                            name.  */
+                         start_symtab (filestring, NULL, (CORE_ADDR) 0);
+                         record_debugformat (debugfmt);
+                       }
+
+                     /* If this is the very first csect seen,
+                        basically `__start'. */
+                     if (just_started)
+                       {
+                         first_object_file_end
+                           = cs->c_value + CSECT_LEN (&main_aux);
+                         just_started = 0;
+                       }
+
+                     file_start_addr =
+                       cs->c_value + ANOFFSET (objfile->section_offsets,
+                                               SECT_OFF_TEXT (objfile));
+                     file_end_addr = file_start_addr + CSECT_LEN (&main_aux);
+
+                     if (cs->c_name && (cs->c_name[0] == '.'
+                                        || cs->c_name[0] == '@'))
+                       {
+                         last_csect_name = cs->c_name;
+                         last_csect_val = cs->c_value;
+                         last_csect_sec = secnum_to_section (cs->c_secnum, objfile);
+                       }
+                   }
+                   continue;
+
+                   /* All other symbols are put into the minimal symbol
+                      table only.  */
+
+                 case XMC_RW:
+                   continue;
+
+                 case XMC_TC0:
+                   continue;
+
+                 case XMC_TC:
+                   continue;
+
+                 default:
+                   /* Ignore the symbol.  */
+                   continue;
+                 }
+             }
+             break;
+
+           case XTY_LD:
+
+             switch (CSECT_SCLAS (&main_aux))
+               {
+               case XMC_PR:
+                 /* a function entry point. */
+               function_entry_point:
+
+                 fcn_start_addr = cs->c_value;
+
+                 /* save the function header info, which will be used
+                    when `.bf' is seen. */
+                 fcn_cs_saved = *cs;
+                 fcn_aux_saved = main_aux;
+                 continue;
+
+               case XMC_GL:
+                 /* shared library function trampoline code entry point. */
+                 continue;
+
+               case XMC_DS:
+                 /* The symbols often have the same names as debug symbols for
+                    functions, and confuse lookup_symbol.  */
+                 continue;
+
+               default:
+                 /* xlc puts each variable in a separate csect, so we get
+                    an XTY_SD for each variable.  But gcc puts several
+                    variables in a csect, so that each variable only gets
+                    an XTY_LD. This will typically be XMC_RW; I suspect
+                    XMC_RO and XMC_BS might be possible too.
+                    These variables are put in the minimal symbol table
+                    only.  */
+                 continue;
+               }
+             break;
+
+           case XTY_CM:
+             /* Common symbols are put into the minimal symbol table only.  */
+             continue;
+
+           default:
+             break;
+           }
+       }
+
+      /* If explicitly specified as a function, treat is as one.  This check
+        evaluates to true for @FIX* bigtoc CSECT symbols, so it must occur
+        after the above CSECT check.  */
+      if (ISFCN (cs->c_type) && cs->c_sclass != C_TPDEF)
+       {
+         bfd_coff_swap_aux_in (abfd, raw_auxptr, cs->c_type, cs->c_sclass,
+                               0, cs->c_naux, &main_aux);
+         goto function_entry_point;
+       }
+
+      switch (cs->c_sclass)
+       {
+
+       case C_FILE:
+
+         /* c_value field contains symnum of next .file entry in table
+            or symnum of first global after last .file. */
+
+         next_file_symnum = cs->c_value;
+
+         /* Complete symbol table for last object file containing
+            debugging information. */
+
+         /* Whether or not there was a csect in the previous file, we
+            have to call `end_stabs' and `start_stabs' to reset
+            type_vector, line_vector, etc. structures.  */
+
+         complete_symtab (filestring, file_start_addr);
+         cur_src_end_addr = file_end_addr;
+         end_symtab (file_end_addr, objfile, SECT_OFF_TEXT (objfile));
+         end_stabs ();
+
+         /* XCOFF, according to the AIX 3.2 documentation, puts the filename
+            in cs->c_name.  But xlc 1.3.0.2 has decided to do things the
+            standard COFF way and put it in the auxent.  We use the auxent if
+            the symbol is ".file" and an auxent exists, otherwise use the symbol
+            itself.  Simple enough.  */
+         if (!strcmp (cs->c_name, ".file") && cs->c_naux > 0)
+           {
+             bfd_coff_swap_aux_in (abfd, raw_auxptr, cs->c_type, cs->c_sclass,
+                                   0, cs->c_naux, &main_aux);
+             filestring = coff_getfilename (&main_aux, objfile);
+           }
+         else
+           filestring = cs->c_name;
+
+         start_stabs ();
+         start_symtab (filestring, (char *) NULL, (CORE_ADDR) 0);
+         record_debugformat (debugfmt);
+         last_csect_name = 0;
+
+         /* reset file start and end addresses. A compilation unit with no text
+            (only data) should have zero file boundaries. */
+         file_start_addr = file_end_addr = 0;
+         break;
+
+       case C_FUN:
+         fcn_stab_saved = *cs;
+         break;
+
+       case C_FCN:
+         if (STREQ (cs->c_name, ".bf"))
+           {
+             CORE_ADDR off = ANOFFSET (objfile->section_offsets,
+                                       SECT_OFF_TEXT (objfile));
+             bfd_coff_swap_aux_in (abfd, raw_auxptr, cs->c_type, cs->c_sclass,
+                                   0, cs->c_naux, &main_aux);
+
+             within_function = 1;
+
+             new = push_context (0, fcn_start_addr + off);
+
+             new->name = define_symbol
+               (fcn_cs_saved.c_value + off,
+                fcn_stab_saved.c_name, 0, 0, objfile);
+             if (new->name != NULL)
+               SYMBOL_SECTION (new->name) = SECT_OFF_TEXT (objfile);
+           }
+         else if (STREQ (cs->c_name, ".ef"))
+           {
+
+             bfd_coff_swap_aux_in (abfd, raw_auxptr, cs->c_type, cs->c_sclass,
+                                   0, cs->c_naux, &main_aux);
+
+             /* The value of .ef is the address of epilogue code;
+                not useful for gdb.  */
+             /* { main_aux.x_sym.x_misc.x_lnsz.x_lnno
+                contains number of lines to '}' */
+
+             if (context_stack_depth <= 0)
+               {               /* We attempted to pop an empty context stack */
+                 complain (&ef_complaint, cs->c_symnum);
+                 within_function = 0;
+                 break;
+               }
+             new = pop_context ();
+             /* Stack must be empty now.  */
+             if (context_stack_depth > 0 || new == NULL)
+               {
+                 complain (&ef_complaint, cs->c_symnum);
+                 within_function = 0;
+                 break;
+               }
+
+             finish_block (new->name, &local_symbols, new->old_blocks,
+                           new->start_addr,
+                           (fcn_cs_saved.c_value
+                            + fcn_aux_saved.x_sym.x_misc.x_fsize
+                            + ANOFFSET (objfile->section_offsets,
+                                        SECT_OFF_TEXT (objfile))),
+                           objfile);
+             within_function = 0;
+           }
+         break;
+
+       case C_BSTAT:
+         /* Begin static block.  */
+         {
+           struct internal_syment symbol;
+
+           read_symbol (&symbol, cs->c_value);
+           static_block_base = symbol.n_value;
+           static_block_section =
+             secnum_to_section (symbol.n_scnum, objfile);
+         }
+         break;
+
+       case C_ESTAT:
+         /* End of static block.  */
+         static_block_base = 0;
+         static_block_section = -1;
+         break;
+
+       case C_ARG:
+       case C_REGPARM:
+       case C_REG:
+       case C_TPDEF:
+       case C_STRTAG:
+       case C_UNTAG:
+       case C_ENTAG:
+         {
+           static struct complaint msg =
+           {"Unrecognized storage class %d.", 0, 0};
+           complain (&msg, cs->c_sclass);
+         }
+         break;
+
+       case C_LABEL:
+       case C_NULL:
+         /* Ignore these.  */
+         break;
+
+       case C_HIDEXT:
+       case C_STAT:
+         break;
+
+       case C_BINCL:
+         /* beginning of include file */
+         /* In xlc output, C_BINCL/C_EINCL pair doesn't show up in sorted
+            order. Thus, when wee see them, we might not know enough info
+            to process them. Thus, we'll be saving them into a table 
+            (inclTable) and postpone their processing. */
+
+         record_include_begin (cs);
+         break;
+
+       case C_EINCL:
+         /* End of include file.  */
+         /* See the comment after case C_BINCL.  */
+         record_include_end (cs);
+         break;
+
+       case C_BLOCK:
+         if (STREQ (cs->c_name, ".bb"))
+           {
+             depth++;
+             new = push_context (depth,
+                                 (cs->c_value
+                                  + ANOFFSET (objfile->section_offsets,
+                                              SECT_OFF_TEXT (objfile))));
+           }
+         else if (STREQ (cs->c_name, ".eb"))
+           {
+             if (context_stack_depth <= 0)
+               {               /* We attempted to pop an empty context stack */
+                 complain (&eb_complaint, cs->c_symnum);
+                 break;
+               }
+             new = pop_context ();
+             if (depth-- != new->depth)
+               {
+                 complain (&eb_complaint, cs->c_symnum);
+                 break;
+               }
+             if (local_symbols && context_stack_depth > 0)
+               {
+                 /* Make a block for the local symbols within.  */
+                 finish_block (new->name, &local_symbols, new->old_blocks,
+                               new->start_addr,
+                               (cs->c_value
+                                + ANOFFSET (objfile->section_offsets,
+                                            SECT_OFF_TEXT (objfile))),
+                               objfile);
+               }
+             local_symbols = new->locals;
+           }
+         break;
+
+       default:
+         process_xcoff_symbol (cs, objfile);
+         break;
+       }
+    }
+
+  if (last_source_file)
+    {
+      struct symtab *s;
+
+      complete_symtab (filestring, file_start_addr);
+      cur_src_end_addr = file_end_addr;
+      s = end_symtab (file_end_addr, objfile, SECT_OFF_TEXT (objfile));
+      /* When reading symbols for the last C_FILE of the objfile, try
+         to make sure that we set pst->symtab to the symtab for the
+         file, not to the _globals_ symtab.  I'm not sure whether this
+         actually works right or when/if it comes up.  */
+      if (pst->symtab == NULL)
+       pst->symtab = s;
+      end_stabs ();
+    }
+}
+
+#define        SYMBOL_DUP(SYMBOL1, SYMBOL2)    \
+  (SYMBOL2) = (struct symbol *)                \
+       obstack_alloc (&objfile->symbol_obstack, sizeof (struct symbol)); \
+  *(SYMBOL2) = *(SYMBOL1);
+
+
+#define        SYMNAME_ALLOC(NAME, ALLOCED)    \
+  (ALLOCED) ? (NAME) : obsavestring ((NAME), strlen (NAME), &objfile->symbol_obstack);
+
+
+static struct type *func_symbol_type;
+static struct type *var_symbol_type;
+
+/* process one xcoff symbol. */
+
+static struct symbol *
+process_xcoff_symbol (register struct coff_symbol *cs, struct objfile *objfile)
+{
+  struct symbol onesymbol;
+  register struct symbol *sym = &onesymbol;
+  struct symbol *sym2 = NULL;
+  char *name, *pp;
+
+  int sec;
+  CORE_ADDR off;
+
+  if (cs->c_secnum < 0)
+    {
+      /* The value is a register number, offset within a frame, etc.,
+         and does not get relocated.  */
+      off = 0;
+      sec = -1;
+    }
+  else
+    {
+      sec = secnum_to_section (cs->c_secnum, objfile);
+      off = ANOFFSET (objfile->section_offsets, sec);
+    }
+
+  name = cs->c_name;
+  if (name[0] == '.')
+    ++name;
+
+  memset (sym, '\0', sizeof (struct symbol));
+
+  /* default assumptions */
+  SYMBOL_VALUE_ADDRESS (sym) = cs->c_value + off;
+  SYMBOL_NAMESPACE (sym) = VAR_NAMESPACE;
+  SYMBOL_SECTION (sym) = secnum_to_section (cs->c_secnum, objfile);
+
+  if (ISFCN (cs->c_type))
+    {
+      /* At this point, we don't know the type of the function.  This
+         will be patched with the type from its stab entry later on in
+         patch_block_stabs (), unless the file was compiled without -g.  */
+
+      SYMBOL_NAME (sym) = SYMNAME_ALLOC (name, symname_alloced);
+      SYMBOL_TYPE (sym) = func_symbol_type;
+
+      SYMBOL_CLASS (sym) = LOC_BLOCK;
+      SYMBOL_DUP (sym, sym2);
+
+      if (cs->c_sclass == C_EXT)
+       add_symbol_to_list (sym2, &global_symbols);
+      else if (cs->c_sclass == C_HIDEXT || cs->c_sclass == C_STAT)
+       add_symbol_to_list (sym2, &file_symbols);
+    }
+  else
+    {
+      /* In case we can't figure out the type, provide default. */
+      SYMBOL_TYPE (sym) = var_symbol_type;
+
+      switch (cs->c_sclass)
+       {
+#if 0
+         /* The values of functions and global symbols are now resolved
+            via the global_sym_chain in stabsread.c.  */
+       case C_FUN:
+         if (fcn_cs_saved.c_sclass == C_EXT)
+           add_stab_to_list (name, &global_stabs);
+         else
+           add_stab_to_list (name, &file_stabs);
+         break;
+
+       case C_GSYM:
+         add_stab_to_list (name, &global_stabs);
+         break;
+#endif
+
+       case C_BCOMM:
+         common_block_start (cs->c_name, objfile);
+         break;
+
+       case C_ECOMM:
+         common_block_end (objfile);
+         break;
+
+       default:
+         complain (&storclass_complaint, cs->c_sclass);
+         /* FALLTHROUGH */
+
+       case C_DECL:
+       case C_PSYM:
+       case C_RPSYM:
+       case C_ECOML:
+       case C_LSYM:
+       case C_RSYM:
+       case C_GSYM:
+
+         {
+           sym = define_symbol (cs->c_value + off, cs->c_name, 0, 0, objfile);
+           if (sym != NULL)
+             {
+               SYMBOL_SECTION (sym) = sec;
+             }
+           return sym;
+         }
+
+       case C_STSYM:
+
+         /* For xlc (not GCC), the 'V' symbol descriptor is used for
+            all statics and we need to distinguish file-scope versus
+            function-scope using within_function.  We do this by
+            changing the string we pass to define_symbol to use 'S'
+            where we need to, which is not necessarily super-clean,
+            but seems workable enough.  */
+
+         if (*name == ':' || (pp = (char *) strchr (name, ':')) == NULL)
+           return NULL;
+
+         ++pp;
+         if (*pp == 'V' && !within_function)
+           *pp = 'S';
+         sym = define_symbol ((cs->c_value
+                               + ANOFFSET (objfile->section_offsets,
+                                           static_block_section)),
+                              cs->c_name, 0, 0, objfile);
+         if (sym != NULL)
+           {
+             SYMBOL_VALUE_ADDRESS (sym) += static_block_base;
+             SYMBOL_SECTION (sym) = static_block_section;
+           }
+         return sym;
+
+       }
+    }
+  return sym2;
+}
+
+/* Extract the file name from the aux entry of a C_FILE symbol.
+   Result is in static storage and is only good for temporary use.  */
+
+static char *
+coff_getfilename (union internal_auxent *aux_entry, struct objfile *objfile)
+{
+  static char buffer[BUFSIZ];
+
+  if (aux_entry->x_file.x_n.x_zeroes == 0)
+    strcpy (buffer,
+           ((struct coff_symfile_info *) objfile->sym_private)->strtbl
+           + aux_entry->x_file.x_n.x_offset);
+  else
+    {
+      strncpy (buffer, aux_entry->x_file.x_fname, FILNMLEN);
+      buffer[FILNMLEN] = '\0';
+    }
+  return (buffer);
+}
+
+/* Set *SYMBOL to symbol number symno in symtbl.  */
+static void
+read_symbol (struct internal_syment *symbol, int symno)
+{
+  int nsyms =
+  ((struct coff_symfile_info *) this_symtab_psymtab->objfile->sym_private)
+  ->symtbl_num_syms;
+  char *stbl =
+  ((struct coff_symfile_info *) this_symtab_psymtab->objfile->sym_private)
+  ->symtbl;
+  if (symno < 0 || symno >= nsyms)
+    {
+      static struct complaint msg =
+      {"Invalid symbol offset", 0, 0};
+      complain (&msg);
+      symbol->n_value = 0;
+      symbol->n_scnum = -1;
+      return;
+    }
+  bfd_coff_swap_sym_in (this_symtab_psymtab->objfile->obfd,
+                       stbl + (symno * local_symesz),
+                       symbol);
+}
+
+/* Get value corresponding to symbol number symno in symtbl.  */
+
+static CORE_ADDR
+read_symbol_nvalue (int symno)
+{
+  struct internal_syment symbol[1];
+
+  read_symbol (symbol, symno);
+  return symbol->n_value;
+}
+
+
+/* Find the address of the function corresponding to symno, where
+   symno is the symbol pointed to by the linetable.  */
+
+static int
+read_symbol_lineno (int symno)
+{
+  struct objfile *objfile = this_symtab_psymtab->objfile;
+  boolean xcoff64 = bfd_xcoff_is_xcoff64 (objfile->obfd);
+
+  struct coff_symfile_info *info =
+    (struct coff_symfile_info *)objfile->sym_private;
+  int nsyms = info->symtbl_num_syms;
+  char *stbl = info->symtbl;
+  char *strtbl = info->strtbl;
+
+  struct internal_syment symbol[1];
+  union internal_auxent main_aux[1];
+
+  if (symno < 0)
+    {
+      complain (&bf_notfound_complaint);
+      return 0;
+    }
+
+  /* Note that just searching for a short distance (e.g. 50 symbols)
+     is not enough, at least in the following case.
+
+     .extern foo
+     [many .stabx entries]
+     [a few functions, referring to foo]
+     .globl foo
+     .bf
+
+     What happens here is that the assembler moves the .stabx entries
+     to right before the ".bf" for foo, but the symbol for "foo" is before
+     all the stabx entries.  See PR gdb/2222.  */
+
+  /* Maintaining a table of .bf entries might be preferable to this search.
+     If I understand things correctly it would need to be done only for
+     the duration of a single psymtab to symtab conversion.  */
+  while (symno < nsyms)
+    {
+      bfd_coff_swap_sym_in (symfile_bfd,
+                           stbl + (symno * local_symesz), symbol);
+      if (symbol->n_sclass == C_FCN)
+       {
+         char *name = xcoff64 ? strtbl + symbol->n_offset : symbol->n_name;
+         if (STREQ (name, ".bf"))
+           goto gotit;
+       }
+      symno += symbol->n_numaux + 1;
+    }
+
+  complain (&bf_notfound_complaint);
+  return 0;
+
+gotit:
+  /* take aux entry and return its lineno */
+  symno++;
+  bfd_coff_swap_aux_in (objfile->obfd, stbl + symno * local_symesz,
+                       symbol->n_type, symbol->n_sclass,
+                       0, symbol->n_numaux, main_aux);
+
+  return main_aux->x_sym.x_misc.x_lnsz.x_lnno;
+}
+
+/* Support for line number handling */
+
+/* This function is called for every section; it finds the outer limits
+ * of the line table (minimum and maximum file offset) so that the
+ * mainline code can read the whole thing for efficiency.
+ */
+static void
+find_linenos (bfd *abfd, sec_ptr asect, PTR vpinfo)
+{
+  struct coff_symfile_info *info;
+  int size, count;
+  file_ptr offset, maxoff;
+
+  count = asect->lineno_count;
+
+  if (!STREQ (asect->name, ".text") || count == 0)
+    return;
+
+  size = count * coff_data (abfd)->local_linesz;
+  info = (struct coff_symfile_info *) vpinfo;
+  offset = asect->line_filepos;
+  maxoff = offset + size;
+
+  if (offset < info->min_lineno_offset || info->min_lineno_offset == 0)
+    info->min_lineno_offset = offset;
+
+  if (maxoff > info->max_lineno_offset)
+    info->max_lineno_offset = maxoff;
+}
+\f
+static void xcoff_psymtab_to_symtab_1 (struct partial_symtab *);
+
+static void
+xcoff_psymtab_to_symtab_1 (struct partial_symtab *pst)
+{
+  struct cleanup *old_chain;
+  int i;
+
+  if (!pst)
+    return;
+
+  if (pst->readin)
+    {
+      fprintf_unfiltered
+       (gdb_stderr, "Psymtab for %s already read in.  Shouldn't happen.\n",
+        pst->filename);
+      return;
+    }
+
+  /* Read in all partial symtabs on which this one is dependent */
+  for (i = 0; i < pst->number_of_dependencies; i++)
+    if (!pst->dependencies[i]->readin)
+      {
+       /* Inform about additional files that need to be read in.  */
+       if (info_verbose)
+         {
+           fputs_filtered (" ", gdb_stdout);
+           wrap_here ("");
+           fputs_filtered ("and ", gdb_stdout);
+           wrap_here ("");
+           printf_filtered ("%s...", pst->dependencies[i]->filename);
+           wrap_here ("");     /* Flush output */
+           gdb_flush (gdb_stdout);
+         }
+       xcoff_psymtab_to_symtab_1 (pst->dependencies[i]);
+      }
+
+  if (((struct symloc *) pst->read_symtab_private)->numsyms != 0)
+    {
+      /* Init stuff necessary for reading in symbols.  */
+      stabsread_init ();
+      buildsym_init ();
+      old_chain = make_cleanup (really_free_pendings, 0);
+
+      read_xcoff_symtab (pst);
+      sort_symtab_syms (pst->symtab);
+
+      do_cleanups (old_chain);
+    }
+
+  pst->readin = 1;
+}
+
+static void xcoff_psymtab_to_symtab (struct partial_symtab *);
+
+/* Read in all of the symbols for a given psymtab for real.
+   Be verbose about it if the user wants that.  */
+
+static void
+xcoff_psymtab_to_symtab (struct partial_symtab *pst)
+{
+  bfd *sym_bfd;
+
+  if (!pst)
+    return;
+
+  if (pst->readin)
+    {
+      fprintf_unfiltered
+       (gdb_stderr, "Psymtab for %s already read in.  Shouldn't happen.\n",
+        pst->filename);
+      return;
+    }
+
+  if (((struct symloc *) pst->read_symtab_private)->numsyms != 0
+      || pst->number_of_dependencies)
+    {
+      /* Print the message now, before reading the string table,
+         to avoid disconcerting pauses.  */
+      if (info_verbose)
+       {
+         printf_filtered ("Reading in symbols for %s...", pst->filename);
+         gdb_flush (gdb_stdout);
+       }
+
+      sym_bfd = pst->objfile->obfd;
+
+      next_symbol_text_func = xcoff_next_symbol_text;
+
+      xcoff_psymtab_to_symtab_1 (pst);
+
+      /* Match with global symbols.  This only needs to be done once,
+         after all of the symtabs and dependencies have been read in.   */
+      scan_file_globals (pst->objfile);
+
+      /* Finish up the debug error message.  */
+      if (info_verbose)
+       printf_filtered ("done.\n");
+    }
+}
+\f
+static void
+xcoff_new_init (struct objfile *objfile)
+{
+  stabsread_new_init ();
+  buildsym_new_init ();
+}
+
+/* Do initialization in preparation for reading symbols from OBJFILE.
+
+   We will only be called if this is an XCOFF or XCOFF-like file.
+   BFD handles figuring out the format of the file, and code in symfile.c
+   uses BFD's determination to vector to us.  */
+
+static void
+xcoff_symfile_init (struct objfile *objfile)
+{
+  /* Allocate struct to keep track of the symfile */
+  objfile->sym_private = xmmalloc (objfile->md,
+                                  sizeof (struct coff_symfile_info));
+
+  /* XCOFF objects may be reordered, so set OBJF_REORDERED.  If we
+     find this causes a significant slowdown in gdb then we could
+     set it in the debug symbol readers only when necessary.  */
+  objfile->flags |= OBJF_REORDERED;
+
+  init_entry_point_info (objfile);
+}
+
+/* Perform any local cleanups required when we are done with a particular
+   objfile.  I.E, we are in the process of discarding all symbol information
+   for an objfile, freeing up all memory held for it, and unlinking the
+   objfile struct from the global list of known objfiles. */
+
+static void
+xcoff_symfile_finish (struct objfile *objfile)
+{
+  if (objfile->sym_private != NULL)
+    {
+      xmfree (objfile->md, objfile->sym_private);
+    }
+
+  /* Start with a fresh include table for the next objfile.  */
+  if (inclTable)
+    {
+      xfree (inclTable);
+      inclTable = NULL;
+    }
+  inclIndx = inclLength = inclDepth = 0;
+}
+
+
+static void
+init_stringtab (bfd *abfd, file_ptr offset, struct objfile *objfile)
+{
+  long length;
+  int val;
+  unsigned char lengthbuf[4];
+  char *strtbl;
+
+  ((struct coff_symfile_info *) objfile->sym_private)->strtbl = NULL;
+
+  if (bfd_seek (abfd, offset, SEEK_SET) < 0)
+    error ("cannot seek to string table in %s: %s",
+          bfd_get_filename (abfd), bfd_errmsg (bfd_get_error ()));
+
+  val = bfd_bread ((char *) lengthbuf, sizeof lengthbuf, abfd);
+  length = bfd_h_get_32 (abfd, lengthbuf);
+
+  /* If no string table is needed, then the file may end immediately
+     after the symbols.  Just return with `strtbl' set to NULL.  */
+
+  if (val != sizeof lengthbuf || length < sizeof lengthbuf)
+    return;
+
+  /* Allocate string table from symbol_obstack. We will need this table
+     as long as we have its symbol table around. */
+
+  strtbl = (char *) obstack_alloc (&objfile->symbol_obstack, length);
+  ((struct coff_symfile_info *) objfile->sym_private)->strtbl = strtbl;
+
+  /* Copy length buffer, the first byte is usually zero and is
+     used for stabs with a name length of zero.  */
+  memcpy (strtbl, lengthbuf, sizeof lengthbuf);
+  if (length == sizeof lengthbuf)
+    return;
+
+  val = bfd_bread (strtbl + sizeof lengthbuf, length - sizeof lengthbuf, abfd);
+
+  if (val != length - sizeof lengthbuf)
+    error ("cannot read string table from %s: %s",
+          bfd_get_filename (abfd), bfd_errmsg (bfd_get_error ()));
+  if (strtbl[length - 1] != '\0')
+    error ("bad symbol file: string table does not end with null character");
+
+  return;
+}
+\f
+/* If we have not yet seen a function for this psymtab, this is 0.  If we
+   have seen one, it is the offset in the line numbers of the line numbers
+   for the psymtab.  */
+static unsigned int first_fun_line_offset;
+
+static struct partial_symtab *xcoff_start_psymtab
+  (struct objfile *, char *, int,
+   struct partial_symbol **, struct partial_symbol **);
+
+/* Allocate and partially fill a partial symtab.  It will be
+   completely filled at the end of the symbol list.
+
+   SYMFILE_NAME is the name of the symbol-file we are reading from, and ADDR
+   is the address relative to which its symbols are (incremental) or 0
+   (normal). */
+
+static struct partial_symtab *
+xcoff_start_psymtab (struct objfile *objfile, char *filename, int first_symnum,
+                    struct partial_symbol **global_syms,
+                    struct partial_symbol **static_syms)
+{
+  struct partial_symtab *result =
+  start_psymtab_common (objfile, objfile->section_offsets,
+                       filename,
+                       /* We fill in textlow later.  */
+                       0,
+                       global_syms, static_syms);
+
+  result->read_symtab_private = (char *)
+    obstack_alloc (&objfile->psymbol_obstack, sizeof (struct symloc));
+  ((struct symloc *) result->read_symtab_private)->first_symnum = first_symnum;
+  result->read_symtab = xcoff_psymtab_to_symtab;
+
+  /* Deduce the source language from the filename for this psymtab. */
+  psymtab_language = deduce_language_from_filename (filename);
+
+  return result;
+}
+
+static struct partial_symtab *xcoff_end_psymtab
+  (struct partial_symtab *, char **, int, int,
+   struct partial_symtab **, int, int);
+
+/* Close off the current usage of PST.  
+   Returns PST, or NULL if the partial symtab was empty and thrown away.
+
+   CAPPING_SYMBOL_NUMBER is the end of pst (exclusive).
+
+   INCLUDE_LIST, NUM_INCLUDES, DEPENDENCY_LIST, and NUMBER_DEPENDENCIES
+   are the information for includes and dependencies.  */
+
+static struct partial_symtab *
+xcoff_end_psymtab (struct partial_symtab *pst, char **include_list,
+                  int num_includes, int capping_symbol_number,
+                  struct partial_symtab **dependency_list,
+                  int number_dependencies, int textlow_not_set)
+{
+  int i;
+  struct objfile *objfile = pst->objfile;
+
+  if (capping_symbol_number != -1)
+    ((struct symloc *) pst->read_symtab_private)->numsyms =
+      capping_symbol_number
+      - ((struct symloc *) pst->read_symtab_private)->first_symnum;
+  ((struct symloc *) pst->read_symtab_private)->lineno_off =
+    first_fun_line_offset;
+  first_fun_line_offset = 0;
+  pst->n_global_syms =
+    objfile->global_psymbols.next - (objfile->global_psymbols.list + pst->globals_offset);
+  pst->n_static_syms =
+    objfile->static_psymbols.next - (objfile->static_psymbols.list + pst->statics_offset);
+
+  pst->number_of_dependencies = number_dependencies;
+  if (number_dependencies)
+    {
+      pst->dependencies = (struct partial_symtab **)
+       obstack_alloc (&objfile->psymbol_obstack,
+                   number_dependencies * sizeof (struct partial_symtab *));
+      memcpy (pst->dependencies, dependency_list,
+             number_dependencies * sizeof (struct partial_symtab *));
+    }
+  else
+    pst->dependencies = 0;
+
+  for (i = 0; i < num_includes; i++)
+    {
+      struct partial_symtab *subpst =
+      allocate_psymtab (include_list[i], objfile);
+
+      subpst->section_offsets = pst->section_offsets;
+      subpst->read_symtab_private =
+       (char *) obstack_alloc (&objfile->psymbol_obstack,
+                               sizeof (struct symloc));
+      ((struct symloc *) subpst->read_symtab_private)->first_symnum = 0;
+      ((struct symloc *) subpst->read_symtab_private)->numsyms = 0;
+      subpst->textlow = 0;
+      subpst->texthigh = 0;
+
+      /* We could save slight bits of space by only making one of these,
+         shared by the entire set of include files.  FIXME-someday.  */
+      subpst->dependencies = (struct partial_symtab **)
+       obstack_alloc (&objfile->psymbol_obstack,
+                      sizeof (struct partial_symtab *));
+      subpst->dependencies[0] = pst;
+      subpst->number_of_dependencies = 1;
+
+      subpst->globals_offset =
+       subpst->n_global_syms =
+       subpst->statics_offset =
+       subpst->n_static_syms = 0;
+
+      subpst->readin = 0;
+      subpst->symtab = 0;
+      subpst->read_symtab = pst->read_symtab;
+    }
+
+  sort_pst_symbols (pst);
+
+  /* If there is already a psymtab or symtab for a file of this name,
+     remove it.  (If there is a symtab, more drastic things also
+     happen.)  This happens in VxWorks.  */
+  free_named_symtabs (pst->filename);
+
+  if (num_includes == 0
+      && number_dependencies == 0
+      && pst->n_global_syms == 0
+      && pst->n_static_syms == 0)
+    {
+      /* Throw away this psymtab, it's empty.  We can't deallocate it, since
+         it is on the obstack, but we can forget to chain it on the list.  */
+      /* Empty psymtabs happen as a result of header files which don't have
+         any symbols in them.  There can be a lot of them.  */
+
+      discard_psymtab (pst);
+
+      /* Indicate that psymtab was thrown away.  */
+      pst = (struct partial_symtab *) NULL;
+    }
+  return pst;
+}
+
+static void swap_sym (struct internal_syment *,
+                     union internal_auxent *, char **, char **,
+                     unsigned int *, struct objfile *);
+
+/* Swap raw symbol at *RAW and put the name in *NAME, the symbol in
+   *SYMBOL, the first auxent in *AUX.  Advance *RAW and *SYMNUMP over
+   the symbol and its auxents.  */
+
+static void
+swap_sym (struct internal_syment *symbol, union internal_auxent *aux,
+         char **name, char **raw, unsigned int *symnump,
+         struct objfile *objfile)
+{
+  bfd_coff_swap_sym_in (objfile->obfd, *raw, symbol);
+  if (symbol->n_zeroes)
+    {
+      /* If it's exactly E_SYMNMLEN characters long it isn't
+         '\0'-terminated.  */
+      if (symbol->n_name[E_SYMNMLEN - 1] != '\0')
+       {
+         /* FIXME: wastes memory for symbols which we don't end up putting
+            into the minimal symbols.  */
+         char *p;
+         p = obstack_alloc (&objfile->psymbol_obstack, E_SYMNMLEN + 1);
+         strncpy (p, symbol->n_name, E_SYMNMLEN);
+         p[E_SYMNMLEN] = '\0';
+         *name = p;
+       }
+      else
+       /* Point to the unswapped name as that persists as long as the
+          objfile does.  */
+       *name = ((struct external_syment *) *raw)->e.e_name;
+    }
+  else if (symbol->n_sclass & 0x80)
+    {
+      *name = ((struct coff_symfile_info *) objfile->sym_private)->debugsec
+       + symbol->n_offset;
+    }
+  else
+    {
+      *name = ((struct coff_symfile_info *) objfile->sym_private)->strtbl
+       + symbol->n_offset;
+    }
+  ++*symnump;
+  *raw += coff_data (objfile->obfd)->local_symesz;
+  if (symbol->n_numaux > 0)
+    {
+      bfd_coff_swap_aux_in (objfile->obfd, *raw, symbol->n_type,
+                           symbol->n_sclass, 0, symbol->n_numaux, aux);
+
+      *symnump += symbol->n_numaux;
+      *raw += coff_data (objfile->obfd)->local_symesz * symbol->n_numaux;
+    }
+}
+
+static void
+scan_xcoff_symtab (struct objfile *objfile)
+{
+  CORE_ADDR toc_offset = 0;    /* toc offset value in data section. */
+  char *filestring = NULL;
+
+  char *namestring;
+  int past_first_source_file = 0;
+  bfd *abfd;
+  asection *bfd_sect;
+  unsigned int nsyms;
+
+  /* Current partial symtab */
+  struct partial_symtab *pst;
+
+  /* List of current psymtab's include files */
+  char **psymtab_include_list;
+  int includes_allocated;
+  int includes_used;
+
+  /* Index within current psymtab dependency list */
+  struct partial_symtab **dependency_list;
+  int dependencies_used, dependencies_allocated;
+
+  char *sraw_symbol;
+  struct internal_syment symbol;
+  union internal_auxent main_aux[5];
+  unsigned int ssymnum;
+
+  char *last_csect_name = NULL;        /* last seen csect's name and value */
+  CORE_ADDR last_csect_val = 0;
+  int last_csect_sec = 0;
+  int misc_func_recorded = 0;  /* true if any misc. function */
+  int textlow_not_set = 1;
+
+  pst = (struct partial_symtab *) 0;
+
+  includes_allocated = 30;
+  includes_used = 0;
+  psymtab_include_list = (char **) alloca (includes_allocated *
+                                          sizeof (char *));
+
+  dependencies_allocated = 30;
+  dependencies_used = 0;
+  dependency_list =
+    (struct partial_symtab **) alloca (dependencies_allocated *
+                                      sizeof (struct partial_symtab *));
+
+  last_source_file = NULL;
+
+  abfd = objfile->obfd;
+
+  sraw_symbol = ((struct coff_symfile_info *) objfile->sym_private)->symtbl;
+  nsyms = ((struct coff_symfile_info *) objfile->sym_private)->symtbl_num_syms;
+  ssymnum = 0;
+  while (ssymnum < nsyms)
+    {
+      int sclass;
+
+      QUIT;
+
+      bfd_coff_swap_sym_in (abfd, sraw_symbol, &symbol);
+      sclass = symbol.n_sclass;
+
+      switch (sclass)
+       {
+       case C_EXT:
+       case C_HIDEXT:
+         {
+           /* The CSECT auxent--always the last auxent.  */
+           union internal_auxent csect_aux;
+           unsigned int symnum_before = ssymnum;
+
+           swap_sym (&symbol, &main_aux[0], &namestring, &sraw_symbol,
+                     &ssymnum, objfile);
+           if (symbol.n_numaux > 1)
+             {
+               bfd_coff_swap_aux_in
+                 (objfile->obfd,
+                  sraw_symbol - coff_data (abfd)->local_symesz,
+                  symbol.n_type,
+                  symbol.n_sclass,
+                  symbol.n_numaux - 1,
+                  symbol.n_numaux,
+                  &csect_aux);
+             }
+           else
+             csect_aux = main_aux[0];
+
+           /* If symbol name starts with ".$" or "$", ignore it.  */
+           if (namestring[0] == '$'
+               || (namestring[0] == '.' && namestring[1] == '$'))
+             break;
+
+           switch (csect_aux.x_csect.x_smtyp & 0x7)
+             {
+             case XTY_SD:
+               switch (csect_aux.x_csect.x_smclas)
+                 {
+                 case XMC_PR:
+                   if (last_csect_name)
+                     {
+                       /* If no misc. function recorded in the last
+                          seen csect, enter it as a function. This
+                          will take care of functions like strcmp()
+                          compiled by xlc.  */
+
+                       if (!misc_func_recorded)
+                         {
+                           RECORD_MINIMAL_SYMBOL
+                             (last_csect_name, last_csect_val,
+                              mst_text, last_csect_sec,
+                              objfile);
+                         }
+
+                       if (pst != NULL)
+                         {
+                           /* We have to allocate one psymtab for
+                              each program csect, because their text
+                              sections need not be adjacent.  */
+                           xcoff_end_psymtab
+                             (pst, psymtab_include_list, includes_used,
+                              symnum_before, dependency_list,
+                              dependencies_used, textlow_not_set);
+                           includes_used = 0;
+                           dependencies_used = 0;
+                           /* Give all psymtabs for this source file the same
+                              name.  */
+                           pst = xcoff_start_psymtab
+                             (objfile,
+                              filestring,
+                              symnum_before,
+                              objfile->global_psymbols.next,
+                              objfile->static_psymbols.next);
+                         }
+                     }
+                   /* Activate the misc_func_recorded mechanism for
+                      compiler- and linker-generated CSECTs like ".strcmp"
+                      and "@FIX1".  */ 
+                   if (namestring && (namestring[0] == '.'
+                                      || namestring[0] == '@'))
+                     {
+                       last_csect_name = namestring;
+                       last_csect_val = symbol.n_value;
+                       last_csect_sec =
+                         secnum_to_section (symbol.n_scnum, objfile);
+                     }
+                   if (pst != NULL)
+                     {
+                       CORE_ADDR highval =
+                       symbol.n_value + csect_aux.x_csect.x_scnlen.l;
+                       if (highval > pst->texthigh)
+                         pst->texthigh = highval;
+                       if (pst->textlow == 0 || symbol.n_value < pst->textlow)
+                         pst->textlow = symbol.n_value;
+                     }
+                   misc_func_recorded = 0;
+                   break;
+
+                 case XMC_RW:
+                 case XMC_TD:
+                   /* Data variables are recorded in the minimal symbol
+                      table, except for section symbols.  */
+                   if (*namestring != '.')
+                     prim_record_minimal_symbol_and_info
+                       (namestring, symbol.n_value,
+                        sclass == C_HIDEXT ? mst_file_data : mst_data,
+                        NULL, secnum_to_section (symbol.n_scnum, objfile),
+                        NULL, objfile);
+                   break;
+
+                 case XMC_TC0:
+                   if (toc_offset)
+                     warning ("More than one XMC_TC0 symbol found.");
+                   toc_offset = symbol.n_value;
+
+                   /* Make TOC offset relative to start address of section.  */
+                   bfd_sect = secnum_to_bfd_section (symbol.n_scnum, objfile);
+                   if (bfd_sect)
+                     toc_offset -= bfd_section_vma (objfile->obfd, bfd_sect);
+                   break;
+
+                 case XMC_TC:
+                   /* These symbols tell us where the TOC entry for a
+                      variable is, not the variable itself.  */
+                   break;
+
+                 default:
+                   break;
+                 }
+               break;
+
+             case XTY_LD:
+               switch (csect_aux.x_csect.x_smclas)
+                 {
+                 case XMC_PR:
+                   /* A function entry point.  */
+
+                   if (first_fun_line_offset == 0 && symbol.n_numaux > 1)
+                     first_fun_line_offset =
+                       main_aux[0].x_sym.x_fcnary.x_fcn.x_lnnoptr;
+                   RECORD_MINIMAL_SYMBOL
+                     (namestring, symbol.n_value,
+                      sclass == C_HIDEXT ? mst_file_text : mst_text,
+                      secnum_to_section (symbol.n_scnum, objfile),
+                      objfile);
+                   break;
+
+                 case XMC_GL:
+                   /* shared library function trampoline code entry
+                      point. */
+
+                   /* record trampoline code entries as
+                      mst_solib_trampoline symbol.  When we lookup mst
+                      symbols, we will choose mst_text over
+                      mst_solib_trampoline. */
+                   RECORD_MINIMAL_SYMBOL
+                     (namestring, symbol.n_value,
+                      mst_solib_trampoline,
+                      secnum_to_section (symbol.n_scnum, objfile),
+                      objfile);
+                   break;
+
+                 case XMC_DS:
+                   /* The symbols often have the same names as
+                      debug symbols for functions, and confuse
+                      lookup_symbol.  */
+                   break;
+
+                 default:
+
+                   /* xlc puts each variable in a separate csect,
+                      so we get an XTY_SD for each variable.  But
+                      gcc puts several variables in a csect, so
+                      that each variable only gets an XTY_LD.  We
+                      still need to record them.  This will
+                      typically be XMC_RW; I suspect XMC_RO and
+                      XMC_BS might be possible too.  */
+                   if (*namestring != '.')
+                     prim_record_minimal_symbol_and_info
+                       (namestring, symbol.n_value,
+                        sclass == C_HIDEXT ? mst_file_data : mst_data,
+                        NULL, secnum_to_section (symbol.n_scnum, objfile),
+                        NULL, objfile);
+                   break;
+                 }
+               break;
+
+             case XTY_CM:
+               switch (csect_aux.x_csect.x_smclas)
+                 {
+                 case XMC_RW:
+                 case XMC_BS:
+                   /* Common variables are recorded in the minimal symbol
+                      table, except for section symbols.  */
+                   if (*namestring != '.')
+                     prim_record_minimal_symbol_and_info
+                       (namestring, symbol.n_value,
+                        sclass == C_HIDEXT ? mst_file_bss : mst_bss,
+                        NULL, secnum_to_section (symbol.n_scnum, objfile),
+                        NULL, objfile);
+                   break;
+                 }
+               break;
+
+             default:
+               break;
+             }
+         }
+         break;
+       case C_FILE:
+         {
+           unsigned int symnum_before;
+
+           symnum_before = ssymnum;
+           swap_sym (&symbol, &main_aux[0], &namestring, &sraw_symbol,
+                     &ssymnum, objfile);
+
+           /* See if the last csect needs to be recorded.  */
+
+           if (last_csect_name && !misc_func_recorded)
+             {
+
+               /* If no misc. function recorded in the last seen csect, enter
+                  it as a function.  This will take care of functions like
+                  strcmp() compiled by xlc.  */
+
+               RECORD_MINIMAL_SYMBOL
+                 (last_csect_name, last_csect_val,
+                  mst_text, last_csect_sec, objfile);
+             }
+
+           if (pst)
+             {
+               xcoff_end_psymtab (pst, psymtab_include_list, includes_used,
+                                  symnum_before, dependency_list,
+                                  dependencies_used, textlow_not_set);
+               includes_used = 0;
+               dependencies_used = 0;
+             }
+           first_fun_line_offset = 0;
+
+           /* XCOFF, according to the AIX 3.2 documentation, puts the
+              filename in cs->c_name.  But xlc 1.3.0.2 has decided to
+              do things the standard COFF way and put it in the auxent.
+              We use the auxent if the symbol is ".file" and an auxent
+              exists, otherwise use the symbol itself.  */
+           if (!strcmp (namestring, ".file") && symbol.n_numaux > 0)
+             {
+               filestring = coff_getfilename (&main_aux[0], objfile);
+             }
+           else
+             filestring = namestring;
+
+           pst = xcoff_start_psymtab (objfile,
+                                      filestring,
+                                      symnum_before,
+                                      objfile->global_psymbols.next,
+                                      objfile->static_psymbols.next);
+           last_csect_name = NULL;
+         }
+         break;
+
+       default:
+         {
+           static struct complaint msg =
+           {"Storage class %d not recognized during scan", 0, 0};
+           complain (&msg, sclass);
+         }
+         /* FALLTHROUGH */
+
+         /* C_FCN is .bf and .ef symbols.  I think it is sufficient
+            to handle only the C_FUN and C_EXT.  */
+       case C_FCN:
+
+       case C_BSTAT:
+       case C_ESTAT:
+       case C_ARG:
+       case C_REGPARM:
+       case C_REG:
+       case C_TPDEF:
+       case C_STRTAG:
+       case C_UNTAG:
+       case C_ENTAG:
+       case C_LABEL:
+       case C_NULL:
+
+         /* C_EINCL means we are switching back to the main file.  But there
+            is no reason to care; the only thing we want to know about
+            includes is the names of all the included (.h) files.  */
+       case C_EINCL:
+
+       case C_BLOCK:
+
+         /* I don't think C_STAT is used in xcoff; C_HIDEXT appears to be
+            used instead.  */
+       case C_STAT:
+
+         /* I don't think the name of the common block (as opposed to the
+            variables within it) is something which is user visible
+            currently.  */
+       case C_BCOMM:
+       case C_ECOMM:
+
+       case C_PSYM:
+       case C_RPSYM:
+
+         /* I think we can ignore C_LSYM; types on xcoff seem to use C_DECL
+            so C_LSYM would appear to be only for locals.  */
+       case C_LSYM:
+
+       case C_AUTO:
+       case C_RSYM:
+         {
+           /* We probably could save a few instructions by assuming that
+              C_LSYM, C_PSYM, etc., never have auxents.  */
+           int naux1 = symbol.n_numaux + 1;
+           ssymnum += naux1;
+           sraw_symbol += bfd_coff_symesz (abfd) * naux1;
+         }
+         break;
+
+       case C_BINCL:
+         {
+           /* Mark down an include file in the current psymtab */
+           enum language tmp_language;
+           swap_sym (&symbol, &main_aux[0], &namestring, &sraw_symbol,
+                     &ssymnum, objfile);
+
+           tmp_language = deduce_language_from_filename (namestring);
+
+           /* Only change the psymtab's language if we've learned
+              something useful (eg. tmp_language is not language_unknown).
+              In addition, to match what start_subfile does, never change
+              from C++ to C.  */
+           if (tmp_language != language_unknown
+               && (tmp_language != language_c
+                   || psymtab_language != language_cplus))
+             psymtab_language = tmp_language;
+
+           /* In C++, one may expect the same filename to come round many
+              times, when code is coming alternately from the main file
+              and from inline functions in other files. So I check to see
+              if this is a file we've seen before -- either the main
+              source file, or a previously included file.
+
+              This seems to be a lot of time to be spending on N_SOL, but
+              things like "break c-exp.y:435" need to work (I
+              suppose the psymtab_include_list could be hashed or put
+              in a binary tree, if profiling shows this is a major hog).  */
+           if (pst && STREQ (namestring, pst->filename))
+             continue;
+           {
+             register int i;
+             for (i = 0; i < includes_used; i++)
+               if (STREQ (namestring, psymtab_include_list[i]))
+                 {
+                   i = -1;
+                   break;
+                 }
+             if (i == -1)
+               continue;
+           }
+           psymtab_include_list[includes_used++] = namestring;
+           if (includes_used >= includes_allocated)
+             {
+               char **orig = psymtab_include_list;
+
+               psymtab_include_list = (char **)
+                 alloca ((includes_allocated *= 2) *
+                         sizeof (char *));
+               memcpy ((PTR) psymtab_include_list, (PTR) orig,
+                       includes_used * sizeof (char *));
+             }
+           continue;
+         }
+       case C_FUN:
+         /* The value of the C_FUN is not the address of the function (it
+            appears to be the address before linking), but as long as it
+            is smaller than the actual address, then find_pc_partial_function
+            will use the minimal symbols instead.  I hope.  */
+
+       case C_GSYM:
+       case C_ECOML:
+       case C_DECL:
+       case C_STSYM:
+         {
+
+           static struct complaint function_outside_compilation_unit = {
+             "function `%s' appears to be defined outside of all compilation units", 0, 0
+           };
+
+           char *p;
+           swap_sym (&symbol, &main_aux[0], &namestring, &sraw_symbol,
+                     &ssymnum, objfile);
+
+           p = (char *) strchr (namestring, ':');
+           if (!p)
+             continue;                 /* Not a debugging symbol.   */
+
+           /* Main processing section for debugging symbols which
+              the initial read through the symbol tables needs to worry
+              about.  If we reach this point, the symbol which we are
+              considering is definitely one we are interested in.
+              p must also contain the (valid) index into the namestring
+              which indicates the debugging type symbol.  */
+
+           switch (p[1])
+             {
+             case 'S':
+               symbol.n_value += ANOFFSET (objfile->section_offsets, SECT_OFF_DATA (objfile));
+#ifdef STATIC_TRANSFORM_NAME
+               namestring = STATIC_TRANSFORM_NAME (namestring);
+#endif
+               add_psymbol_to_list (namestring, p - namestring,
+                                    VAR_NAMESPACE, LOC_STATIC,
+                                    &objfile->static_psymbols,
+                                    0, symbol.n_value,
+                                    psymtab_language, objfile);
+               continue;
+
+             case 'G':
+               symbol.n_value += ANOFFSET (objfile->section_offsets, SECT_OFF_DATA (objfile));
+               /* The addresses in these entries are reported to be
+                  wrong.  See the code that reads 'G's for symtabs. */
+               add_psymbol_to_list (namestring, p - namestring,
+                                    VAR_NAMESPACE, LOC_STATIC,
+                                    &objfile->global_psymbols,
+                                    0, symbol.n_value,
+                                    psymtab_language, objfile);
+               continue;
+
+             case 'T':
+               /* When a 'T' entry is defining an anonymous enum, it
+                  may have a name which is the empty string, or a
+                  single space.  Since they're not really defining a
+                  symbol, those shouldn't go in the partial symbol
+                  table.  We do pick up the elements of such enums at
+                  'check_enum:', below.  */
+               if (p >= namestring + 2
+                   || (p == namestring + 1
+                       && namestring[0] != ' '))
+                 {
+                   add_psymbol_to_list (namestring, p - namestring,
+                                        STRUCT_NAMESPACE, LOC_TYPEDEF,
+                                        &objfile->static_psymbols,
+                                        symbol.n_value, 0,
+                                        psymtab_language, objfile);
+                   if (p[2] == 't')
+                     {
+                       /* Also a typedef with the same name.  */
+                       add_psymbol_to_list (namestring, p - namestring,
+                                            VAR_NAMESPACE, LOC_TYPEDEF,
+                                            &objfile->static_psymbols,
+                                            symbol.n_value, 0,
+                                            psymtab_language, objfile);
+                       p += 1;
+                     }
+                   /* The semantics of C++ state that "struct foo { ... }"
+                      also defines a typedef for "foo".  Unfortuantely, cfront
+                      never makes the typedef when translating from C++ to C.
+                      We make the typedef here so that "ptype foo" works as
+                      expected for cfront translated code.  */
+                   else if (psymtab_language == language_cplus)
+                     {
+                       /* Also a typedef with the same name.  */
+                       add_psymbol_to_list (namestring, p - namestring,
+                                            VAR_NAMESPACE, LOC_TYPEDEF,
+                                            &objfile->static_psymbols,
+                                            symbol.n_value, 0,
+                                            psymtab_language, objfile);
+                     }
+                 }
+               goto check_enum;
+
+             case 't':
+               if (p != namestring)    /* a name is there, not just :T... */
+                 {
+                   add_psymbol_to_list (namestring, p - namestring,
+                                        VAR_NAMESPACE, LOC_TYPEDEF,
+                                        &objfile->static_psymbols,
+                                        symbol.n_value, 0,
+                                        psymtab_language, objfile);
+                 }
+             check_enum:
+               /* If this is an enumerated type, we need to
+                  add all the enum constants to the partial symbol
+                  table.  This does not cover enums without names, e.g.
+                  "enum {a, b} c;" in C, but fortunately those are
+                  rare.  There is no way for GDB to find those from the
+                  enum type without spending too much time on it.  Thus
+                  to solve this problem, the compiler needs to put out the
+                  enum in a nameless type.  GCC2 does this.  */
+
+               /* We are looking for something of the form
+                  <name> ":" ("t" | "T") [<number> "="] "e"
+                  {<constant> ":" <value> ","} ";".  */
+
+               /* Skip over the colon and the 't' or 'T'.  */
+               p += 2;
+               /* This type may be given a number.  Also, numbers can come
+                  in pairs like (0,26).  Skip over it.  */
+               while ((*p >= '0' && *p <= '9')
+                      || *p == '(' || *p == ',' || *p == ')'
+                      || *p == '=')
+                 p++;
+
+               if (*p++ == 'e')
+                 {
+                   /* The aix4 compiler emits extra crud before the members.  */
+                   if (*p == '-')
+                     {
+                       /* Skip over the type (?).  */
+                       while (*p != ':')
+                         p++;
+
+                       /* Skip over the colon.  */
+                       p++;
+                     }
+
+                   /* We have found an enumerated type.  */
+                   /* According to comments in read_enum_type
+                      a comma could end it instead of a semicolon.
+                      I don't know where that happens.
+                      Accept either.  */
+                   while (*p && *p != ';' && *p != ',')
+                     {
+                       char *q;
+
+                       /* Check for and handle cretinous dbx symbol name
+                          continuation!  */
+                       if (*p == '\\' || (*p == '?' && p[1] == '\0'))
+                         p = next_symbol_text (objfile);
+
+                       /* Point to the character after the name
+                          of the enum constant.  */
+                       for (q = p; *q && *q != ':'; q++)
+                         ;
+                       /* Note that the value doesn't matter for
+                          enum constants in psymtabs, just in symtabs.  */
+                       add_psymbol_to_list (p, q - p,
+                                            VAR_NAMESPACE, LOC_CONST,
+                                            &objfile->static_psymbols, 0,
+                                            0, psymtab_language, objfile);
+                       /* Point past the name.  */
+                       p = q;
+                       /* Skip over the value.  */
+                       while (*p && *p != ',')
+                         p++;
+                       /* Advance past the comma.  */
+                       if (*p)
+                         p++;
+                     }
+                 }
+               continue;
+
+             case 'c':
+               /* Constant, e.g. from "const" in Pascal.  */
+               add_psymbol_to_list (namestring, p - namestring,
+                                    VAR_NAMESPACE, LOC_CONST,
+                                    &objfile->static_psymbols, symbol.n_value,
+                                    0, psymtab_language, objfile);
+               continue;
+
+             case 'f':
+               if (! pst)
+                 {
+                   int name_len = p - namestring;
+                   char *name = xmalloc (name_len + 1);
+                   memcpy (name, namestring, name_len);
+                   name[name_len] = '\0';
+                   complain (&function_outside_compilation_unit, name);
+                   xfree (name);
+                 }
+               symbol.n_value += ANOFFSET (objfile->section_offsets, SECT_OFF_TEXT (objfile));
+               add_psymbol_to_list (namestring, p - namestring,
+                                    VAR_NAMESPACE, LOC_BLOCK,
+                                    &objfile->static_psymbols,
+                                    0, symbol.n_value,
+                                    psymtab_language, objfile);
+               continue;
+
+               /* Global functions were ignored here, but now they
+                  are put into the global psymtab like one would expect.
+                  They're also in the minimal symbol table.  */
+             case 'F':
+               if (! pst)
+                 {
+                   int name_len = p - namestring;
+                   char *name = xmalloc (name_len + 1);
+                   memcpy (name, namestring, name_len);
+                   name[name_len] = '\0';
+                   complain (&function_outside_compilation_unit, name);
+                   xfree (name);
+                 }
+               symbol.n_value += ANOFFSET (objfile->section_offsets, SECT_OFF_TEXT (objfile));
+               add_psymbol_to_list (namestring, p - namestring,
+                                    VAR_NAMESPACE, LOC_BLOCK,
+                                    &objfile->global_psymbols,
+                                    0, symbol.n_value,
+                                    psymtab_language, objfile);
+               continue;
+
+               /* Two things show up here (hopefully); static symbols of
+                  local scope (static used inside braces) or extensions
+                  of structure symbols.  We can ignore both.  */
+             case 'V':
+             case '(':
+             case '0':
+             case '1':
+             case '2':
+             case '3':
+             case '4':
+             case '5':
+             case '6':
+             case '7':
+             case '8':
+             case '9':
+             case '-':
+             case '#':         /* for symbol identification (used in live ranges) */
+               /* added to support cfront stabs strings */
+             case 'Z':         /* for definition continuations */
+             case 'P':         /* for prototypes */
+               continue;
+
+             case ':':
+               /* It is a C++ nested symbol.  We don't need to record it
+                  (I don't think); if we try to look up foo::bar::baz,
+                  then symbols for the symtab containing foo should get
+                  read in, I think.  */
+               /* Someone says sun cc puts out symbols like
+                  /foo/baz/maclib::/usr/local/bin/maclib,
+                  which would get here with a symbol type of ':'.  */
+               continue;
+
+             default:
+               /* Unexpected symbol descriptor.  The second and subsequent stabs
+                  of a continued stab can show up here.  The question is
+                  whether they ever can mimic a normal stab--it would be
+                  nice if not, since we certainly don't want to spend the
+                  time searching to the end of every string looking for
+                  a backslash.  */
+
+               complain (&unknown_symchar_complaint, p[1]);
+
+               /* Ignore it; perhaps it is an extension that we don't
+                  know about.  */
+               continue;
+             }
+         }
+       }
+    }
+
+  if (pst)
+    {
+      xcoff_end_psymtab (pst, psymtab_include_list, includes_used,
+                        ssymnum, dependency_list,
+                        dependencies_used, textlow_not_set);
+    }
+
+  /* Record the toc offset value of this symbol table into objfile structure.
+     If no XMC_TC0 is found, toc_offset should be zero. Another place to obtain
+     this information would be file auxiliary header. */
+
+  ((struct coff_symfile_info *) objfile->sym_private)->toc_offset = toc_offset;
+}
+
+/* Return the toc offset value for a given objfile.  */
+
+CORE_ADDR
+get_toc_offset (struct objfile *objfile)
+{
+  if (objfile)
+    return ((struct coff_symfile_info *) objfile->sym_private)->toc_offset;
+  return 0;
+}
+
+/* Scan and build partial symbols for a symbol file.
+   We have been initialized by a call to dbx_symfile_init, which 
+   put all the relevant info into a "struct dbx_symfile_info",
+   hung off the objfile structure.
+
+   SECTION_OFFSETS contains offsets relative to which the symbols in the
+   various sections are (depending where the sections were actually loaded).
+   MAINLINE is true if we are reading the main symbol
+   table (as opposed to a shared lib or dynamically loaded file).  */
+
+static void
+xcoff_initial_scan (struct objfile *objfile, int mainline)
+{
+  bfd *abfd;
+  int val;
+  struct cleanup *back_to;
+  int num_symbols;             /* # of symbols */
+  file_ptr symtab_offset;      /* symbol table and */
+  file_ptr stringtab_offset;   /* string table file offsets */
+  struct coff_symfile_info *info;
+  char *name;
+  unsigned int size;
+
+  info = (struct coff_symfile_info *) objfile->sym_private;
+  symfile_bfd = abfd = objfile->obfd;
+  name = objfile->name;
+
+  num_symbols = bfd_get_symcount (abfd);       /* # of symbols */
+  symtab_offset = obj_sym_filepos (abfd);      /* symbol table file offset */
+  stringtab_offset = symtab_offset +
+    num_symbols * coff_data (abfd)->local_symesz;
+
+  info->min_lineno_offset = 0;
+  info->max_lineno_offset = 0;
+  bfd_map_over_sections (abfd, find_linenos, info);
+
+  if (num_symbols > 0)
+    {
+      /* Read the string table.  */
+      init_stringtab (abfd, stringtab_offset, objfile);
+
+      /* Read the .debug section, if present.  */
+      {
+       sec_ptr secp;
+       bfd_size_type length;
+       char *debugsec = NULL;
+
+       secp = bfd_get_section_by_name (abfd, ".debug");
+       if (secp)
+         {
+           length = bfd_section_size (abfd, secp);
+           if (length)
+             {
+               debugsec =
+                 (char *) obstack_alloc (&objfile->symbol_obstack, length);
+
+               if (!bfd_get_section_contents (abfd, secp, debugsec,
+                                              (file_ptr) 0, length))
+                 {
+                   error ("Error reading .debug section of `%s': %s",
+                          name, bfd_errmsg (bfd_get_error ()));
+                 }
+             }
+         }
+       ((struct coff_symfile_info *) objfile->sym_private)->debugsec =
+         debugsec;
+      }
+    }
+
+  /* Read the symbols.  We keep them in core because we will want to
+     access them randomly in read_symbol*.  */
+  val = bfd_seek (abfd, symtab_offset, SEEK_SET);
+  if (val < 0)
+    error ("Error reading symbols from %s: %s",
+          name, bfd_errmsg (bfd_get_error ()));
+  size = coff_data (abfd)->local_symesz * num_symbols;
+  ((struct coff_symfile_info *) objfile->sym_private)->symtbl =
+    obstack_alloc (&objfile->symbol_obstack, size);
+  ((struct coff_symfile_info *) objfile->sym_private)->symtbl_num_syms =
+    num_symbols;
+
+  val = bfd_bread (((struct coff_symfile_info *) objfile->sym_private)->symtbl,
+                  size, abfd);
+  if (val != size)
+    perror_with_name ("reading symbol table");
+
+  /* If we are reinitializing, or if we have never loaded syms yet, init */
+  if (mainline
+      || (objfile->global_psymbols.size == 0
+         && objfile->static_psymbols.size == 0))
+    /* I'm not sure how how good num_symbols is; the rule of thumb in
+       init_psymbol_list was developed for a.out.  On the one hand,
+       num_symbols includes auxents.  On the other hand, it doesn't
+       include N_SLINE.  */
+    init_psymbol_list (objfile, num_symbols);
+
+  free_pending_blocks ();
+  back_to = make_cleanup (really_free_pendings, 0);
+
+  init_minimal_symbol_collection ();
+  make_cleanup_discard_minimal_symbols ();
+
+  /* Now that the symbol table data of the executable file are all in core,
+     process them and define symbols accordingly.  */
+
+  scan_xcoff_symtab (objfile);
+
+  /* Install any minimal symbols that have been collected as the current
+     minimal symbols for this objfile. */
+
+  install_minimal_symbols (objfile);
+
+  do_cleanups (back_to);
+}
+\f
+static void
+xcoff_symfile_offsets (struct objfile *objfile, struct section_addr_info *addrs)
+{
+  asection *sect = NULL;
+  int i;
+
+  objfile->num_sections = SECT_OFF_MAX;
+  objfile->section_offsets = (struct section_offsets *)
+    obstack_alloc (&objfile->psymbol_obstack, SIZEOF_SECTION_OFFSETS);
+
+  /* Initialize the section indexes for future use. */
+  sect = bfd_get_section_by_name (objfile->obfd, ".text");
+  if (sect) 
+    objfile->sect_index_text = sect->index;
+
+  sect = bfd_get_section_by_name (objfile->obfd, ".data");
+  if (sect) 
+    objfile->sect_index_data = sect->index;
+
+  sect = bfd_get_section_by_name (objfile->obfd, ".bss");
+  if (sect) 
+    objfile->sect_index_bss = sect->index;
+
+  sect = bfd_get_section_by_name (objfile->obfd, ".rodata");
+  if (sect) 
+    objfile->sect_index_rodata = sect->index;
+
+  for (i = 0; i < objfile->num_sections; ++i)
+    {
+      /* syms_from_objfile kindly subtracts from addr the
+        bfd_section_vma of the .text section.  This strikes me as
+        wrong--whether the offset to be applied to symbol reading is
+        relative to the start address of the section depends on the
+        symbol format.  In any event, this whole "addr" concept is
+        pretty broken (it doesn't handle any section but .text
+        sensibly), so just ignore the addr parameter and use 0.
+        rs6000-nat.c will set the correct section offsets via
+        objfile_relocate.  */
+       (objfile->section_offsets)->offsets[i] = 0;
+    }
+}
+
+/* Register our ability to parse symbols for xcoff BFD files.  */
+
+static struct sym_fns xcoff_sym_fns =
+{
+
+  /* It is possible that coff and xcoff should be merged as
+     they do have fundamental similarities (for example, the extra storage
+     classes used for stabs could presumably be recognized in any COFF file).
+     However, in addition to obvious things like all the csect hair, there are
+     some subtler differences between xcoffread.c and coffread.c, notably
+     the fact that coffread.c has no need to read in all the symbols, but
+     xcoffread.c reads all the symbols and does in fact randomly access them
+     (in C_BSTAT and line number processing).  */
+
+  bfd_target_xcoff_flavour,
+
+  xcoff_new_init,              /* sym_new_init: init anything gbl to entire symtab */
+  xcoff_symfile_init,          /* sym_init: read initial info, setup for sym_read() */
+  xcoff_initial_scan,          /* sym_read: read a symbol file into symtab */
+  xcoff_symfile_finish,                /* sym_finish: finished with file, cleanup */
+  xcoff_symfile_offsets,       /* sym_offsets: xlate offsets ext->int form */
+  NULL                         /* next: pointer to next struct sym_fns */
+};
+
+void
+_initialize_xcoffread (void)
+{
+  add_symtab_fns (&xcoff_sym_fns);
+
+  func_symbol_type = init_type (TYPE_CODE_FUNC, 1, 0,
+                               "<function, no debug info>", NULL);
+  TYPE_TARGET_TYPE (func_symbol_type) = builtin_type_int;
+  var_symbol_type =
+    init_type (TYPE_CODE_INT, TARGET_INT_BIT / HOST_CHAR_BIT, 0,
+              "<variable, no debug info>", NULL);
+}