aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authornobody <>2002-09-20 15:07:16 +0000
committernobody <>2002-09-20 15:07:16 +0000
commit9dcc0b141cc6b94354177de13359f44691713b19 (patch)
tree4bf74b436a04aab8dafb5645a95ce289fc8c3173
parent148ea30ef6e624235f31f27ee7a285c7529eb68a (diff)
downloadgdb-9dcc0b141cc6b94354177de13359f44691713b19.zip
gdb-9dcc0b141cc6b94354177de13359f44691713b19.tar.gz
gdb-9dcc0b141cc6b94354177de13359f44691713b19.tar.bz2
This commit was manufactured by cvs2svn to create branch
'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
-rw-r--r--gdb/ChangeLog11415
-rw-r--r--gdb/Makefile.in2595
-rw-r--r--gdb/ada-lang.c8311
-rw-r--r--gdb/c-lang.c652
-rw-r--r--gdb/coffread.c2166
-rw-r--r--gdb/dbxread.c3599
-rw-r--r--gdb/dwarf2read.c6938
-rw-r--r--gdb/dwarfread.c3788
-rw-r--r--gdb/hpread.c6310
-rw-r--r--gdb/mdebugread.c5021
-rw-r--r--gdb/symfile.c3340
-rw-r--r--gdb/symfile.h328
-rw-r--r--gdb/symtab.c4063
-rw-r--r--gdb/symtab.h1414
-rw-r--r--gdb/xcoffread.c3049
15 files changed, 62989 insertions, 0 deletions
diff --git a/gdb/ChangeLog b/gdb/ChangeLog
new file mode 100644
index 0000000..ec776f7
--- /dev/null
+++ b/gdb/ChangeLog
@@ -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
+
+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
index 0000000..ca17a2b
--- /dev/null
+++ b/gdb/Makefile.in
@@ -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
index 0000000..2838df7
--- /dev/null
+++ b/gdb/ada-lang.c
@@ -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);
+
+
+
+/* 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);
+}
+
+
+ /* 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;
+}
+
+
+ /* 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));
+}
+
+
+ /* 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);
+}
+
+
+ /* 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));
+
+ }
+}
+
+ /* 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;
+}
+
+
+ /* 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);
+}
+
+
+ /* 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);
+ }
+ }
+}
+
+
+ /* 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;
+ }
+}
+
+
+ /* 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;
+}
+
+
+ /* 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;
+}
+
+
+
+ /* 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);
+}
+
+
+
+
+
+/* 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));
+}
+
+
+ /* 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);
+}
+
+
+ /* 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");
+ }
+}
+
+
+ /* 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"));
+}
+
+
+ /* 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;
+}
+
+
+
+ /* 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}
+};
+
+ /* 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
index 0000000..6bbd6d9
--- /dev/null
+++ b/gdb/c-lang.c
@@ -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);
+}
+
+/* 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;
+ }
+}
+
+
+
+/* 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}
+};
+
+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
index 0000000..d794a7d
--- /dev/null
+++ b/gdb/coffread.c
@@ -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 *);
+
+/* 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;
+}
+
+/* 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;
+}
+
+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);
+}
+
+/* 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 ();
+}
+
+
+/* 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;
+}
+
+/* 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;
+ }
+ }
+}
+
+/* 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);
+}
+
+/* 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;
+ }
+}
+
+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);
+ }
+ }
+ }
+ }
+}
+
+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;
+}
+
+/* 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);
+}
+
+/* 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);
+}
+
+/* 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;
+}
+
+/* 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
index 0000000..6592b74
--- /dev/null
+++ b/gdb/dbxread.c
@@ -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 */
+
+
+/* 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)
+
+
+/* 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;
+
+/* 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};
+
+/* 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;
+}
+
+
+
+/* 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
+
+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);
+}
+
+/* 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 ();
+}
+
+
+/* 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;
+}
+
+/* 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;
+}
+
+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 ();
+}
+
+
+/* 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;
+}
+
+/* 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);
+}
+
+/* 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);
+}
+
+/* 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);
+}
+
+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
index 0000000..4ef683c
--- /dev/null
+++ b/gdb/dwarf2read.c
@@ -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);
+}
+
+
+/* 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
index 0000000..9c4201d
--- /dev/null
+++ b/gdb/dwarfread.c
@@ -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
index 0000000..4cc5f18
--- /dev/null
+++ b/gdb/hpread.c
@@ -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)
+
+/* 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))
+
+/* 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;
+
+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 *);
+
+
+/* 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";
+
+/* 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 */
+
+
+/* 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);
+ }
+ }
+}
+
+
+
+#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)
+
+
+
+/* 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;
+}
+
+
+
+/* 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. */
+
+
+/* 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 */
+
+
+/* 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);
+ }
+}
+
+
+/* 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;
+}
+
+
+/* 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;
+}
+
+
+/* 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;
+}
+
+
+/* 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));
+}
+
+
+
+
+/* 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
index 0000000..1695afd
--- /dev/null
+++ b/gdb/mdebugread.c
@@ -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)
+
+
+/* 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)
+
+/* 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)))
+
+/* 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 *);
+
+/* 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");
+}
+
+/* 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
+}
+
+/* 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;
+ }
+}
+
+
+/* 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;
+ }
+ }
+}
+
+/* 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;
+}
+
+/* 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;
+}
+
+/* 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));
+}
+
+
+/* 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;
+}
+
+/* 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);
+}
+
+
+/* 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
index 0000000..66bbf71
--- /dev/null
+++ b/gdb/symfile.c
@@ -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;
+
+
+/* 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));
+}
+
+/* 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);
+}
+
+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
+}
+
+/* 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 ();
+}
+
+
+
+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;
+}
+
+/* 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;
+}
+
+
+/* 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
+}
+
+/* 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);
+}
+
+/* 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
index 0000000..39eb308
--- /dev/null
+++ b/gdb/symfile.h
@@ -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
index 0000000..a432292
--- /dev/null
+++ b/gdb/symtab.c
@@ -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);
+}
+
+/* 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);
+}
+
+
+/* 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
+}
+
+
+
+
+
+/* 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));
+}
+
+/* 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;
+}
+
+
+/* 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));
+}
+
+
+#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);
+}
+
+/* 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;
+}
+
+/* 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;
+}
+
+
+/* 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);
+}
+
+
+/* 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);
+}
+
+
+/* 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 */
+
+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
index 0000000..a78607d
--- /dev/null
+++ b/gdb/symtab.h
@@ -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
+
+
+
+/* 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)
+
+
+/* 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
+
+/* 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
+
+
+/* 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
+
+
+/* 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))
+
+
+/* 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;
+};
+
+
+
+/* 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)
+
+
+/* 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
index 0000000..0e85125
--- /dev/null
+++ b/gdb/xcoffread.c
@@ -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"
+
+
+/* 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;
+
+
+/* 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);
+
+
+/* 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;
+}
+
+/* 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
+ /* *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;
+}
+
+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");
+ }
+}
+
+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;
+}
+
+/* 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);
+}
+
+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);
+}