Add the fullname_syntax testsuite variable. This allows GDB to make sure
[deliverable/binutils-gdb.git] / gdb / dwarf2read.c
index f9081a3c867eb0141a3ac9b96bc7ff98ecf36037..a6a76842eea63196bda404f95f5ff11649194848 100644 (file)
@@ -1,4 +1,5 @@
 /* DWARF 2 debugging format support for GDB.
+
    Copyright 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003,
    2004
    Free Software Foundation, Inc.
@@ -45,6 +46,8 @@
 #include "dwarf2loc.h"
 #include "cp-support.h"
 #include "hashtab.h"
+#include "command.h"
+#include "gdbcmd.h"
 
 #include <fcntl.h>
 #include "gdb_string.h"
@@ -166,6 +169,17 @@ struct dwarf2_per_objfile
   char *macinfo_buffer;
   char *ranges_buffer;
   char *loc_buffer;
+
+  /* A list of all the compilation units.  This is used to locate
+     the target compilation unit of a particular reference.  */
+  struct dwarf2_per_cu_data **all_comp_units;
+
+  /* The number of compilation units in ALL_COMP_UNITS.  */
+  int n_comp_units;
+
+  /* A chain of compilation units that are currently read in, so that
+     they can be freed later.  */
+  struct dwarf2_per_cu_data *read_in_chain;
 };
 
 static struct dwarf2_per_objfile *dwarf2_per_objfile;
@@ -206,43 +220,45 @@ asection *dwarf_eh_frame_section;
 /* 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 */
-
-    /* Offset to the first byte of this compilation unit header in the 
-     * .debug_info section, for resolving relative reference dies. */
-
-    unsigned int offset;
-
-    /* Pointer to this compilation unit header in the .debug_info
-     * section */
+{
+  unsigned long length;
+  short version;
+  unsigned int abbrev_offset;
+  unsigned char addr_size;
+  unsigned char signed_addr_p;
 
-    char *cu_head_ptr;
+  /* Size of file offsets; either 4 or 8.  */
+  unsigned int offset_size;
 
-    /* Pointer to the first die of this compilatio unit.  This will
-     * be the first byte following the compilation unit header. */
+  /* Size of the length field; either 4 or 12.  */
+  unsigned int initial_length_size;
 
-    char *first_die_ptr;
+  /* Offset to the first byte of this compilation unit header in the
+     .debug_info section, for resolving relative reference dies.  */
+  unsigned int offset;
 
-    /* Pointer to the next compilation unit header in the program. */
+  /* Pointer to this compilation unit header in the .debug_info
+     section.  */
+  char *cu_head_ptr;
 
-    struct comp_unit_head *next;
+  /* Pointer to the first die of this compilation unit.  This will be
+     the first byte following the compilation unit header.  */
+  char *first_die_ptr;
 
-    /* Base address of this compilation unit.  */
+  /* Pointer to the next compilation unit header in the program.  */
+  struct comp_unit_head *next;
 
-    CORE_ADDR base_address;
+  /* Base address of this compilation unit.  */
+  CORE_ADDR base_address;
 
-    /* Non-zero if base_address has been set.  */
+  /* Non-zero if base_address has been set.  */
+  int base_known;
+};
 
-    int base_known;
-  };
+/* Fixed size for the DIE hash table.  */
+#ifndef REF_HASH_SIZE
+#define REF_HASH_SIZE 1021
+#endif
 
 /* Internal state when decoding a particular compilation unit.  */
 struct dwarf2_cu
@@ -262,6 +278,8 @@ struct dwarf2_cu
   enum language language;
   const struct language_defn *language_defn;
 
+  const char *producer;
+
   /* 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().
@@ -297,6 +315,36 @@ struct dwarf2_cu
      unit, including partial DIEs.  */
   struct obstack comp_unit_obstack;
 
+  /* When multiple dwarf2_cu structures are living in memory, this field
+     chains them all together, so that they can be released efficiently.
+     We will probably also want a generation counter so that most-recently-used
+     compilation units are cached...  */
+  struct dwarf2_per_cu_data *read_in_chain;
+
+  /* Backchain to our per_cu entry if the tree has been built.  */
+  struct dwarf2_per_cu_data *per_cu;
+
+  /* How many compilation units ago was this CU last referenced?  */
+  int last_used;
+
+  /* A hash table of die offsets for following references.  */
+  struct die_info *die_ref_table[REF_HASH_SIZE];
+
+  /* Full DIEs if read in.  */
+  struct die_info *dies;
+
+  /* A set of pointers to dwarf2_per_cu_data objects for compilation
+     units referenced by this one.  Only set during full symbol processing;
+     partial symbol tables do not have dependencies.  */
+  htab_t dependencies;
+
+  /* Mark used when releasing cached dies.  */
+  unsigned int mark : 1;
+
+  /* This flag will be set if this compilation unit might include
+     inter-compilation-unit references.  */
+  unsigned int has_form_ref_addr : 1;
+
   /* This flag will be set if this compilation unit includes any
      DW_TAG_namespace DIEs.  If we know that there are explicit
      DIEs for namespaces, we don't need to try to infer them
@@ -304,6 +352,37 @@ struct dwarf2_cu
   unsigned int has_namespace_info : 1;
 };
 
+/* Persistent data held for a compilation unit, even when not
+   processing it.  We put a pointer to this structure in the
+   read_symtab_private field of the psymtab.  If we encounter
+   inter-compilation-unit references, we also maintain a sorted
+   list of all compilation units.  */
+
+struct dwarf2_per_cu_data
+{
+  /* The start offset and length of this compilation unit.  2**31-1
+     bytes should suffice to store the length of any compilation unit
+     - if it doesn't, GDB will fall over anyway.  */
+  unsigned long offset;
+  unsigned long length : 31;
+
+  /* Flag indicating this compilation unit will be read in before
+     any of the current compilation units are processed.  */
+  unsigned long queued : 1;
+
+  /* Set iff currently read in.  */
+  struct dwarf2_cu *cu;
+
+  /* If full symbols for this CU have been read in, then this field
+     holds a map of DIE offsets to types.  It isn't always possible
+     to reconstruct this information later, so we have to preserve
+     it.  */
+  htab_t type_hash;
+
+  /* The partial symbol table associated with this compilation unit.  */
+  struct partial_symtab *psymtab;
+};
+
 /* 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.  */
@@ -380,6 +459,7 @@ struct partial_die_info
        sometimes DW_TAG_MIPS_linkage_name or a string computed in some
        other fashion.  */
     char *name;
+    char *dirname;
 
     /* The scope to prepend to our children.  This is generally
        allocated on the comp_unit_obstack, so will disappear
@@ -492,13 +572,6 @@ struct dwarf_block
 #define ATTR_ALLOC_CHUNK 4
 #endif
 
-/* 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];
-
 /* Allocate fields for structs, unions and enums in this size.  */
 #ifndef DW_FIELD_ALLOC_CHUNK
 #define DW_FIELD_ALLOC_CHUNK 4
@@ -516,19 +589,6 @@ static int isreg;          /* Object lives in register.
                                   decode_locdesc's return value is
                                   the register number.  */
 
-/* We put a pointer to this structure in the read_symtab_private field
-   of the psymtab.  */
-
-struct dwarf2_pinfo
-  {
-    /* Offset in .debug_info for this compilation unit. */
-
-    unsigned long dwarf_info_offset;
-  };
-
-#define PST_PRIVATE(p) ((struct dwarf2_pinfo *)(p)->read_symtab_private)
-#define DWARF_INFO_OFFSET(p) (PST_PRIVATE(p)->dwarf_info_offset)
-
 /* 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.  */
@@ -582,19 +642,46 @@ struct field_info
     int nfnfields;
   };
 
+/* One item on the queue of compilation units to read in full symbols
+   for.  */
+struct dwarf2_queue_item
+{
+  struct dwarf2_per_cu_data *per_cu;
+  struct dwarf2_queue_item *next;
+};
+
+/* The current queue.  */
+static struct dwarf2_queue_item *dwarf2_queue, *dwarf2_queue_tail;
+
+/* Loaded secondary compilation units are kept in memory until they
+   have not been referenced for the processing of this many
+   compilation units.  Set this to zero to disable caching.  Cache
+   sizes of up to at least twenty will improve startup time for
+   typical inter-CU-reference binaries, at an obvious memory cost.  */
+static int dwarf2_max_cache_age = 5;
+static void
+show_dwarf2_max_cache_age (struct ui_file *file, int from_tty,
+                          struct cmd_list_element *c, const char *value)
+{
+  fprintf_filtered (file, _("\
+The upper bound on the age of cached dwarf2 compilation units is %s.\n"),
+                   value);
+}
+
+
 /* Various complaints about symbol reading that don't abort the process */
 
 static void
 dwarf2_statement_list_fits_in_line_number_section_complaint (void)
 {
   complaint (&symfile_complaints,
-            "statement list doesn't fit in .debug_line section");
+            _("statement list doesn't fit in .debug_line section"));
 }
 
 static void
 dwarf2_complex_location_expr_complaint (void)
 {
-  complaint (&symfile_complaints, "location expression too complex");
+  complaint (&symfile_complaints, _("location expression too complex"));
 }
 
 static void
@@ -602,7 +689,7 @@ dwarf2_const_value_length_mismatch_complaint (const char *arg1, int arg2,
                                              int arg3)
 {
   complaint (&symfile_complaints,
-            "const value length mismatch for '%s', got %d, expected %d", arg1,
+            _("const value length mismatch for '%s', got %d, expected %d"), arg1,
             arg2, arg3);
 }
 
@@ -610,14 +697,14 @@ static void
 dwarf2_macros_too_long_complaint (void)
 {
   complaint (&symfile_complaints,
-            "macro info runs off end of `.debug_macinfo' section");
+            _("macro info runs off end of `.debug_macinfo' section"));
 }
 
 static void
 dwarf2_macro_malformed_definition_complaint (const char *arg1)
 {
   complaint (&symfile_complaints,
-            "macro debug info contains a malformed macro definition:\n`%s'",
+            _("macro debug info contains a malformed macro definition:\n`%s'"),
             arg1);
 }
 
@@ -625,7 +712,7 @@ static void
 dwarf2_invalid_attrib_class_complaint (const char *arg1, const char *arg2)
 {
   complaint (&symfile_complaints,
-            "invalid attribute class or form for '%s' in '%s'", arg1, arg2);
+            _("invalid attribute class or form for '%s' in '%s'"), arg1, arg2);
 }
 
 /* local function prototypes */
@@ -689,8 +776,7 @@ static char *read_partial_die (struct partial_die_info *,
                               bfd *, char *, struct dwarf2_cu *);
 
 static struct partial_die_info *find_partial_die (unsigned long,
-                                                 struct dwarf2_cu *,
-                                                 struct dwarf2_cu **);
+                                                 struct dwarf2_cu *);
 
 static void fixup_partial_die (struct partial_die_info *,
                               struct dwarf2_cu *);
@@ -778,17 +864,14 @@ static struct type *die_type (struct die_info *, struct dwarf2_cu *);
 static struct type *die_containing_type (struct die_info *,
                                         struct dwarf2_cu *);
 
-#if 0
-static struct type *type_at_offset (unsigned int, struct objfile *);
-#endif
-
 static struct type *tag_type_to_type (struct die_info *, struct dwarf2_cu *);
 
 static void read_type_die (struct die_info *, struct dwarf2_cu *);
 
 static char *determine_prefix (struct die_info *die, struct dwarf2_cu *);
 
-static char *typename_concat (const char *prefix, const char *suffix);
+static char *typename_concat (struct obstack *, const char *prefix, const char *suffix,
+                             struct dwarf2_cu *);
 
 static void read_typedef (struct die_info *, struct dwarf2_cu *);
 
@@ -845,6 +928,9 @@ static CORE_ADDR decode_locdesc (struct dwarf_block *, struct dwarf2_cu *);
 
 static void read_array_type (struct die_info *, struct dwarf2_cu *);
 
+static enum dwarf_array_dim_ordering read_array_order (struct die_info *, 
+                                                      struct dwarf2_cu *);
+
 static void read_tag_pointer_type (struct die_info *, struct dwarf2_cu *);
 
 static void read_tag_ptr_to_member_type (struct die_info *,
@@ -874,8 +960,6 @@ static struct die_info *read_die_and_siblings (char *info_ptr, bfd *abfd,
 
 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 dwarf2_cu *);
 
 static char *dwarf2_linkage_name (struct die_info *, struct dwarf2_cu *);
@@ -909,16 +993,17 @@ 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 void store_in_ref_table (unsigned int, struct die_info *,
+                               struct dwarf2_cu *);
 
 static unsigned int dwarf2_get_ref_die_offset (struct attribute *,
                                               struct dwarf2_cu *);
 
 static int dwarf2_get_attr_constant_value (struct attribute *, int);
 
-static struct die_info *follow_die_ref (unsigned int);
+static struct die_info *follow_die_ref (struct die_info *,
+                                       struct attribute *,
+                                       struct dwarf2_cu *);
 
 static struct type *dwarf2_fundamental_type (struct objfile *, int,
                                             struct dwarf2_cu *);
@@ -958,6 +1043,39 @@ static hashval_t partial_die_hash (const void *item);
 
 static int partial_die_eq (const void *item_lhs, const void *item_rhs);
 
+static struct dwarf2_per_cu_data *dwarf2_find_containing_comp_unit
+  (unsigned long offset, struct objfile *objfile);
+
+static struct dwarf2_per_cu_data *dwarf2_find_comp_unit
+  (unsigned long offset, struct objfile *objfile);
+
+static void free_one_comp_unit (void *);
+
+static void free_cached_comp_units (void *);
+
+static void age_cached_comp_units (void);
+
+static void free_one_cached_comp_unit (void *);
+
+static void set_die_type (struct die_info *, struct type *,
+                         struct dwarf2_cu *);
+
+static void reset_die_and_siblings_types (struct die_info *,
+                                         struct dwarf2_cu *);
+
+static void create_all_comp_units (struct objfile *);
+
+static struct dwarf2_cu *load_full_comp_unit (struct dwarf2_per_cu_data *);
+
+static void process_full_comp_unit (struct dwarf2_per_cu_data *);
+
+static void dwarf2_add_dependence (struct dwarf2_cu *,
+                                  struct dwarf2_per_cu_data *);
+
+static void dwarf2_mark (struct dwarf2_cu *);
+
+static void dwarf2_clear_marks (struct dwarf2_per_cu_data *);
+
 /* Try to locate the sections we need for DWARF 2 debugging
    information and return true if we have enough to do something.  */
 
@@ -995,47 +1113,47 @@ dwarf2_locate_sections (bfd *ignore_abfd, asection *sectp, void *ignore_ptr)
 {
   if (strcmp (sectp->name, INFO_SECTION) == 0)
     {
-      dwarf2_per_objfile->info_size = bfd_get_section_size_before_reloc (sectp);
+      dwarf2_per_objfile->info_size = bfd_get_section_size (sectp);
       dwarf_info_section = sectp;
     }
   else if (strcmp (sectp->name, ABBREV_SECTION) == 0)
     {
-      dwarf2_per_objfile->abbrev_size = bfd_get_section_size_before_reloc (sectp);
+      dwarf2_per_objfile->abbrev_size = bfd_get_section_size (sectp);
       dwarf_abbrev_section = sectp;
     }
   else if (strcmp (sectp->name, LINE_SECTION) == 0)
     {
-      dwarf2_per_objfile->line_size = bfd_get_section_size_before_reloc (sectp);
+      dwarf2_per_objfile->line_size = bfd_get_section_size (sectp);
       dwarf_line_section = sectp;
     }
   else if (strcmp (sectp->name, PUBNAMES_SECTION) == 0)
     {
-      dwarf2_per_objfile->pubnames_size = bfd_get_section_size_before_reloc (sectp);
+      dwarf2_per_objfile->pubnames_size = bfd_get_section_size (sectp);
       dwarf_pubnames_section = sectp;
     }
   else if (strcmp (sectp->name, ARANGES_SECTION) == 0)
     {
-      dwarf2_per_objfile->aranges_size = bfd_get_section_size_before_reloc (sectp);
+      dwarf2_per_objfile->aranges_size = bfd_get_section_size (sectp);
       dwarf_aranges_section = sectp;
     }
   else if (strcmp (sectp->name, LOC_SECTION) == 0)
     {
-      dwarf2_per_objfile->loc_size = bfd_get_section_size_before_reloc (sectp);
+      dwarf2_per_objfile->loc_size = bfd_get_section_size (sectp);
       dwarf_loc_section = sectp;
     }
   else if (strcmp (sectp->name, MACINFO_SECTION) == 0)
     {
-      dwarf2_per_objfile->macinfo_size = bfd_get_section_size_before_reloc (sectp);
+      dwarf2_per_objfile->macinfo_size = bfd_get_section_size (sectp);
       dwarf_macinfo_section = sectp;
     }
   else if (strcmp (sectp->name, STR_SECTION) == 0)
     {
-      dwarf2_per_objfile->str_size = bfd_get_section_size_before_reloc (sectp);
+      dwarf2_per_objfile->str_size = bfd_get_section_size (sectp);
       dwarf_str_section = sectp;
     }
   else if (strcmp (sectp->name, FRAME_SECTION) == 0)
     {
-      dwarf2_per_objfile->frame_size = bfd_get_section_size_before_reloc (sectp);
+      dwarf2_per_objfile->frame_size = bfd_get_section_size (sectp);
       dwarf_frame_section = sectp;
     }
   else if (strcmp (sectp->name, EH_FRAME_SECTION) == 0)
@@ -1043,13 +1161,13 @@ dwarf2_locate_sections (bfd *ignore_abfd, asection *sectp, void *ignore_ptr)
       flagword aflag = bfd_get_section_flags (ignore_abfd, sectp);
       if (aflag & SEC_HAS_CONTENTS)
         {
-          dwarf2_per_objfile->eh_frame_size = bfd_get_section_size_before_reloc (sectp);
+          dwarf2_per_objfile->eh_frame_size = bfd_get_section_size (sectp);
           dwarf_eh_frame_section = sectp;
         }
     }
   else if (strcmp (sectp->name, RANGES_SECTION) == 0)
     {
-      dwarf2_per_objfile->ranges_size = bfd_get_section_size_before_reloc (sectp);
+      dwarf2_per_objfile->ranges_size = bfd_get_section_size (sectp);
       dwarf_ranges_section = sectp;
     }
 }
@@ -1152,7 +1270,7 @@ dwarf2_build_psymtabs_easy (struct objfile *objfile, int mainline)
 #endif
 
 /* Read in the comp unit header information from the debug_info at
-   info_ptr. */
+   info_ptr.  */
 
 static char *
 read_comp_unit_head (struct comp_unit_head *cu_header,
@@ -1173,7 +1291,7 @@ read_comp_unit_head (struct comp_unit_head *cu_header,
   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");
+                   _("read_comp_unit_head: dwarf from non elf file"));
   cu_header->signed_addr_p = signed_addr;
   return info_ptr;
 }
@@ -1187,21 +1305,21 @@ partial_read_comp_unit_head (struct comp_unit_head *header, char *info_ptr,
   info_ptr = read_comp_unit_head (header, info_ptr, abfd);
 
   if (header->version != 2)
-    error ("Dwarf Error: wrong version in compilation unit header "
-          "(is %d, should be %d) [in module %s]", header->version,
+    error (_("Dwarf Error: wrong version in compilation unit header "
+          "(is %d, should be %d) [in module %s]"), header->version,
           2, bfd_get_filename (abfd));
 
   if (header->abbrev_offset >= dwarf2_per_objfile->abbrev_size)
-    error ("Dwarf Error: bad offset (0x%lx) in compilation unit header "
-          "(offset 0x%lx + 6) [in module %s]",
+    error (_("Dwarf Error: bad offset (0x%lx) in compilation unit header "
+          "(offset 0x%lx + 6) [in module %s]"),
           (long) header->abbrev_offset,
           (long) (beg_of_comp_unit - dwarf2_per_objfile->info_buffer),
           bfd_get_filename (abfd));
 
   if (beg_of_comp_unit + header->length + header->initial_length_size
       > dwarf2_per_objfile->info_buffer + dwarf2_per_objfile->info_size)
-    error ("Dwarf Error: bad length (0x%lx) in compilation unit header "
-          "(offset 0x%lx + 0) [in module %s]",
+    error (_("Dwarf Error: bad length (0x%lx) in compilation unit header "
+          "(offset 0x%lx + 0) [in module %s]"),
           (long) header->length,
           (long) (beg_of_comp_unit - dwarf2_per_objfile->info_buffer),
           bfd_get_filename (abfd));
@@ -1238,10 +1356,8 @@ dwarf2_create_include_psymtab (char *name, struct partial_symtab *pst,
 
   /* No private part is necessary for include psymtabs.  This property
      can be used to differentiate between such include psymtabs and
-     the regular ones.  If it ever happens that a regular psymtab can
-     legitimally have a NULL PST_PRIVATE part, then we'll have to add a
-     dedicated field for that in the dwarf2_pinfo structure.  */
-  PST_PRIVATE (subpst) = NULL;
+     the regular ones.  */
+  subpst->read_symtab_private = NULL;
 }
 
 /* Read the Line Number Program data and extract the list of files
@@ -1284,10 +1400,17 @@ dwarf2_build_psymtabs_hard (struct objfile *objfile, int mainline)
   char *beg_of_comp_unit;
   struct partial_die_info comp_unit_die;
   struct partial_symtab *pst;
+  struct cleanup *back_to;
   CORE_ADDR lowpc, highpc, baseaddr;
 
   info_ptr = dwarf2_per_objfile->info_buffer;
 
+  /* Any cached compilation units will be linked by the per-objfile
+     read_in_chain.  Make sure to free them when we're done.  */
+  back_to = make_cleanup (free_cached_comp_units, NULL);
+
+  create_all_comp_units (objfile);
+
   /* Since the objects we're extracting from .debug_info vary in
      length, only the individual functions to extract them (like
      read_comp_unit_head and load_partial_die) can really know whether
@@ -1328,12 +1451,12 @@ dwarf2_build_psymtabs_hard (struct objfile *objfile, int mainline)
 
       cu.list_in_scope = &file_symbols;
 
-      cu.partial_dies = NULL;
-
       /* Read the abbrevs for this compilation unit into a table */
       dwarf2_read_abbrevs (abfd, &cu);
       make_cleanup (dwarf2_free_abbrev_table, &cu);
 
+      this_cu = dwarf2_find_comp_unit (cu.header.offset, objfile);
+
       /* Read the compilation unit die */
       abbrev = peek_die_abbrev (info_ptr, &bytes_read, &cu);
       info_ptr = read_partial_die (&comp_unit_die, abbrev, bytes_read,
@@ -1349,14 +1472,35 @@ dwarf2_build_psymtabs_hard (struct objfile *objfile, int mainline)
                                  objfile->global_psymbols.next,
                                  objfile->static_psymbols.next);
 
-      pst->read_symtab_private = (char *)
-       obstack_alloc (&objfile->objfile_obstack, sizeof (struct dwarf2_pinfo));
-      DWARF_INFO_OFFSET (pst) = beg_of_comp_unit - dwarf2_per_objfile->info_buffer;
+      if (comp_unit_die.dirname)
+       pst->dirname = xstrdup (comp_unit_die.dirname);
+
+      pst->read_symtab_private = (char *) this_cu;
+
       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;
 
+      /* If this compilation unit was already read in, free the
+        cached copy in order to read it in again.  This is
+        necessary because we skipped some symbols when we first
+        read in the compilation unit (see load_partial_dies).
+        This problem could be avoided, but the benefit is
+        unclear.  */
+      if (this_cu->cu != NULL)
+       free_one_cached_comp_unit (this_cu->cu);
+
+      cu.per_cu = this_cu;
+
+      /* Note that this is a pointer to our stack frame, being
+        added to a global data structure.  It will be cleaned up
+        in free_stack_comp_unit when we finish with this
+        compilation unit.  */
+      this_cu->cu = &cu;
+
+      this_cu->psymtab = pst;
+
       /* 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. */
@@ -1398,6 +1542,9 @@ dwarf2_build_psymtabs_hard (struct objfile *objfile, int mainline)
          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;
+
       if (comp_unit_die.has_stmt_list)
         {
           /* Get the list of files included in the current compilation unit,
@@ -1405,11 +1552,125 @@ dwarf2_build_psymtabs_hard (struct objfile *objfile, int mainline)
           dwarf2_build_include_psymtabs (&cu, &comp_unit_die, pst);
         }
 
-      info_ptr = beg_of_comp_unit + cu.header.length
-                                  + cu.header.initial_length_size;
-
       do_cleanups (back_to_inner);
     }
+  do_cleanups (back_to);
+}
+
+/* Load the DIEs for a secondary CU into memory.  */
+
+static void
+load_comp_unit (struct dwarf2_per_cu_data *this_cu, struct objfile *objfile)
+{
+  bfd *abfd = objfile->obfd;
+  char *info_ptr, *beg_of_comp_unit;
+  struct partial_die_info comp_unit_die;
+  struct dwarf2_cu *cu;
+  struct abbrev_info *abbrev;
+  unsigned int bytes_read;
+  struct cleanup *back_to;
+
+  info_ptr = dwarf2_per_objfile->info_buffer + this_cu->offset;
+  beg_of_comp_unit = info_ptr;
+
+  cu = xmalloc (sizeof (struct dwarf2_cu));
+  memset (cu, 0, sizeof (struct dwarf2_cu));
+
+  obstack_init (&cu->comp_unit_obstack);
+
+  cu->objfile = objfile;
+  info_ptr = partial_read_comp_unit_head (&cu->header, info_ptr, abfd);
+
+  /* Complete the cu_header.  */
+  cu->header.offset = beg_of_comp_unit - dwarf2_per_objfile->info_buffer;
+  cu->header.first_die_ptr = info_ptr;
+  cu->header.cu_head_ptr = beg_of_comp_unit;
+
+  /* Read the abbrevs for this compilation unit into a table.  */
+  dwarf2_read_abbrevs (abfd, cu);
+  back_to = make_cleanup (dwarf2_free_abbrev_table, cu);
+
+  /* Read the compilation unit die.  */
+  abbrev = peek_die_abbrev (info_ptr, &bytes_read, cu);
+  info_ptr = read_partial_die (&comp_unit_die, abbrev, bytes_read,
+                              abfd, info_ptr, cu);
+
+  /* Set the language we're debugging.  */
+  set_cu_language (comp_unit_die.language, cu);
+
+  /* Link this compilation unit into the compilation unit tree.  */
+  this_cu->cu = cu;
+  cu->per_cu = this_cu;
+
+  /* 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)
+    load_partial_dies (abfd, info_ptr, 0, cu);
+
+  do_cleanups (back_to);
+}
+
+/* Create a list of all compilation units in OBJFILE.  We do this only
+   if an inter-comp-unit reference is found; presumably if there is one,
+   there will be many, and one will occur early in the .debug_info section.
+   So there's no point in building this list incrementally.  */
+
+static void
+create_all_comp_units (struct objfile *objfile)
+{
+  int n_allocated;
+  int n_comp_units;
+  struct dwarf2_per_cu_data **all_comp_units;
+  char *info_ptr = dwarf2_per_objfile->info_buffer;
+
+  n_comp_units = 0;
+  n_allocated = 10;
+  all_comp_units = xmalloc (n_allocated
+                           * sizeof (struct dwarf2_per_cu_data *));
+  
+  while (info_ptr < dwarf2_per_objfile->info_buffer + dwarf2_per_objfile->info_size)
+    {
+      struct comp_unit_head cu_header;
+      char *beg_of_comp_unit;
+      struct dwarf2_per_cu_data *this_cu;
+      unsigned long offset;
+      int bytes_read;
+
+      offset = info_ptr - dwarf2_per_objfile->info_buffer;
+
+      /* Read just enough information to find out where the next
+        compilation unit is.  */
+      cu_header.initial_length_size = 0;
+      cu_header.length = read_initial_length (objfile->obfd, info_ptr,
+                                             &cu_header, &bytes_read);
+
+      /* Save the compilation unit for later lookup.  */
+      this_cu = obstack_alloc (&objfile->objfile_obstack,
+                              sizeof (struct dwarf2_per_cu_data));
+      memset (this_cu, 0, sizeof (*this_cu));
+      this_cu->offset = offset;
+      this_cu->length = cu_header.length + cu_header.initial_length_size;
+
+      if (n_comp_units == n_allocated)
+       {
+         n_allocated *= 2;
+         all_comp_units = xrealloc (all_comp_units,
+                                    n_allocated
+                                    * sizeof (struct dwarf2_per_cu_data *));
+       }
+      all_comp_units[n_comp_units++] = this_cu;
+
+      info_ptr = info_ptr + this_cu->length;
+    }
+
+  dwarf2_per_objfile->all_comp_units
+    = obstack_alloc (&objfile->objfile_obstack,
+                    n_comp_units * sizeof (struct dwarf2_per_cu_data *));
+  memcpy (dwarf2_per_objfile->all_comp_units, all_comp_units,
+         n_comp_units * sizeof (struct dwarf2_per_cu_data *));
+  xfree (all_comp_units);
+  dwarf2_per_objfile->n_comp_units = n_comp_units;
 }
 
 /* Process all loaded DIEs for compilation unit CU, starting at FIRST_DIE.
@@ -1502,7 +1763,8 @@ scan_partial_symbols (struct partial_die_info *first_die, CORE_ADDR *lowpc,
 /* Functions used to compute the fully scoped name of a partial DIE.
 
    Normally, this is simple.  For C++, the parent DIE's fully scoped
-   name is concatenated with "::" and the partial DIE's name.
+   name is concatenated with "::" and the partial DIE's name.  For
+   Java, the same thing occurs except that "." is used instead of "::".
    Enumerators are an exception; they use the scope of their parent
    enumeration type, i.e. the name of the enumeration type is not
    prepended to the enumerator.
@@ -1528,15 +1790,13 @@ partial_die_parent_scope (struct partial_die_info *pdi,
 {
   char *grandparent_scope;
   struct partial_die_info *parent, *real_pdi;
-  struct dwarf2_cu *spec_cu;
 
   /* We need to look at our parent DIE; if we have a DW_AT_specification,
      then this means the parent of the specification DIE.  */
 
   real_pdi = pdi;
-  spec_cu = cu;
   while (real_pdi->has_specification)
-    real_pdi = find_partial_die (real_pdi->spec_offset, spec_cu, &spec_cu);
+    real_pdi = find_partial_die (real_pdi->spec_offset, cu);
 
   parent = real_pdi->die_parent;
   if (parent == NULL)
@@ -1547,7 +1807,7 @@ partial_die_parent_scope (struct partial_die_info *pdi,
 
   fixup_partial_die (parent, cu);
 
-  grandparent_scope = partial_die_parent_scope (parent, spec_cu);
+  grandparent_scope = partial_die_parent_scope (parent, cu);
 
   if (parent->tag == DW_TAG_namespace
       || parent->tag == DW_TAG_structure_type
@@ -1557,8 +1817,8 @@ partial_die_parent_scope (struct partial_die_info *pdi,
       if (grandparent_scope == NULL)
        parent->scope = parent->name;
       else
-       parent->scope = obconcat (&cu->comp_unit_obstack, grandparent_scope,
-                                 "::", parent->name);
+       parent->scope = typename_concat (&cu->comp_unit_obstack, grandparent_scope,
+                                        parent->name, cu);
     }
   else if (parent->tag == DW_TAG_enumeration_type)
     /* Enumerators should not get the name of the enumeration as a prefix.  */
@@ -1569,7 +1829,7 @@ partial_die_parent_scope (struct partial_die_info *pdi,
         function-local names?  For partial symbols, we should probably be
         ignoring them.  */
       complaint (&symfile_complaints,
-                "unhandled containing DIE tag %d for DIE at %d",
+                _("unhandled containing DIE tag %d for DIE at %d"),
                 parent->tag, pdi->offset);
       parent->scope = grandparent_scope;
     }
@@ -1590,7 +1850,7 @@ partial_die_full_name (struct partial_die_info *pdi,
   if (parent_scope == NULL)
     return NULL;
   else
-    return concat (parent_scope, "::", pdi->name, NULL);
+    return typename_concat (NULL, parent_scope, pdi->name, cu);
 }
 
 static void
@@ -1708,14 +1968,16 @@ add_partial_symbol (struct partial_die_info *pdi, struct dwarf2_cu *cu)
        return;
       add_psymbol_to_list (actual_name, strlen (actual_name),
                           STRUCT_DOMAIN, LOC_TYPEDEF,
-                          cu->language == language_cplus
+                          (cu->language == language_cplus
+                           || cu->language == language_java)
                           ? &objfile->global_psymbols
                           : &objfile->static_psymbols,
                           0, (CORE_ADDR) 0, cu->language, objfile);
 
-      if (cu->language == language_cplus)
+      if (cu->language == language_cplus
+          || cu->language == language_java)
        {
-         /* For C++, these implicitly act as typedefs as well. */
+         /* For C++ and Java, these implicitly act as typedefs as well. */
          add_psymbol_to_list (actual_name, strlen (actual_name),
                               VAR_DOMAIN, LOC_TYPEDEF,
                               &objfile->global_psymbols,
@@ -1725,7 +1987,8 @@ add_partial_symbol (struct partial_die_info *pdi, struct dwarf2_cu *cu)
     case DW_TAG_enumerator:
       add_psymbol_to_list (actual_name, strlen (actual_name),
                           VAR_DOMAIN, LOC_CONST,
-                          cu->language == language_cplus
+                          (cu->language == language_cplus
+                           || cu->language == language_java)
                           ? &objfile->global_psymbols
                           : &objfile->static_psymbols,
                           0, (CORE_ADDR) 0, cu->language, objfile);
@@ -1805,7 +2068,8 @@ static void
 guess_structure_name (struct partial_die_info *struct_pdi,
                      struct dwarf2_cu *cu)
 {
-  if (cu->language == language_cplus
+  if ((cu->language == language_cplus
+       || cu->language == language_java)
       && cu->has_namespace_info == 0
       && struct_pdi->has_children)
     {
@@ -1817,16 +2081,14 @@ guess_structure_name (struct partial_die_info *struct_pdi,
 
       struct partial_die_info *child_pdi = struct_pdi->die_child;
       struct partial_die_info *real_pdi;
-      struct dwarf2_cu *spec_cu;
 
       /* If this DIE (this DIE's specification, if any) has a parent, then
         we should not do this.  We'll prepend the parent's fully qualified
          name when we create the partial symbol.  */
 
       real_pdi = struct_pdi;
-      spec_cu = cu;
       while (real_pdi->has_specification)
-       real_pdi = find_partial_die (real_pdi->spec_offset, spec_cu, &spec_cu);
+       real_pdi = find_partial_die (real_pdi->spec_offset, cu);
 
       if (real_pdi->die_parent != NULL)
        return;
@@ -1836,7 +2098,8 @@ guess_structure_name (struct partial_die_info *struct_pdi,
          if (child_pdi->tag == DW_TAG_subprogram)
            {
              char *actual_class_name
-               = class_name_from_physname (child_pdi->name);
+               = language_class_name_from_physname (cu->language_defn,
+                                                    child_pdi->name);
              if (actual_class_name != NULL)
                {
                  struct_pdi->name
@@ -1870,7 +2133,7 @@ add_partial_enumeration (struct partial_die_info *enum_pdi,
   while (pdi)
     {
       if (pdi->tag != DW_TAG_enumerator || pdi->name == NULL)
-       complaint (&symfile_complaints, "malformed enumerator DIE ignored");
+       complaint (&symfile_complaints, _("malformed enumerator DIE ignored"));
       else
        add_partial_symbol (pdi, cu);
       pdi = pdi->die_sibling;
@@ -1897,7 +2160,7 @@ peek_die_abbrev (char *info_ptr, int *bytes_read, struct dwarf2_cu *cu)
   abbrev = dwarf2_lookup_abbrev (abbrev_number, cu);
   if (!abbrev)
     {
-      error ("Dwarf Error: Could not find abbrev number %d [in module %s]", abbrev_number,
+      error (_("Dwarf Error: Could not find abbrev number %d [in module %s]"), abbrev_number,
                      bfd_get_filename (abfd));
     }
 
@@ -1947,7 +2210,7 @@ skip_one_die (char *info_ptr, struct abbrev_info *abbrev,
          read_attribute (&attr, &abbrev->attrs[i],
                          abfd, info_ptr, cu);
          if (attr.form == DW_FORM_ref_addr)
-           complaint (&symfile_complaints, "ignoring absolute DW_AT_sibling");
+           complaint (&symfile_complaints, _("ignoring absolute DW_AT_sibling"));
          else
            return dwarf2_per_objfile->info_buffer
              + dwarf2_get_ref_die_offset (&attr, cu);
@@ -2012,7 +2275,7 @@ skip_one_die (char *info_ptr, struct abbrev_info *abbrev,
          goto skip_attribute;
 
        default:
-         error ("Dwarf Error: Cannot handle %s in DWARF reader [in module %s]",
+         error (_("Dwarf Error: Cannot handle %s in DWARF reader [in module %s]"),
                 dwarf_form_name (form),
                 bfd_get_filename (abfd));
        }
@@ -2056,40 +2319,127 @@ dwarf2_psymtab_to_symtab (struct partial_symtab *pst)
     {
       if (pst->readin)
        {
-         warning ("bug: psymtab for %s is already read in.", pst->filename);
+         warning (_("bug: psymtab for %s is already read in."), pst->filename);
        }
       else
        {
          if (info_verbose)
            {
-             printf_filtered ("Reading in symbols for %s...", pst->filename);
+             printf_filtered (_("Reading in symbols for %s..."), pst->filename);
              gdb_flush (gdb_stdout);
            }
 
+         /* Restore our global data.  */
+         dwarf2_per_objfile = objfile_data (pst->objfile,
+                                            dwarf2_objfile_data_key);
+
          psymtab_to_symtab_1 (pst);
 
          /* Finish up the debug error message.  */
          if (info_verbose)
-           printf_filtered ("done.\n");
+           printf_filtered (_("done.\n"));
+       }
+    }
+}
+
+/* Add PER_CU to the queue.  */
+
+static void
+queue_comp_unit (struct dwarf2_per_cu_data *per_cu)
+{
+  struct dwarf2_queue_item *item;
+
+  per_cu->queued = 1;
+  item = xmalloc (sizeof (*item));
+  item->per_cu = per_cu;
+  item->next = NULL;
+
+  if (dwarf2_queue == NULL)
+    dwarf2_queue = item;
+  else
+    dwarf2_queue_tail->next = item;
+
+  dwarf2_queue_tail = item;
+}
+
+/* Process the queue.  */
+
+static void
+process_queue (struct objfile *objfile)
+{
+  struct dwarf2_queue_item *item, *next_item;
+
+  /* Initially, there is just one item on the queue.  Load its DIEs,
+     and the DIEs of any other compilation units it requires,
+     transitively.  */
+
+  for (item = dwarf2_queue; item != NULL; item = item->next)
+    {
+      /* Read in this compilation unit.  This may add new items to
+        the end of the queue.  */
+      load_full_comp_unit (item->per_cu);
+
+      item->per_cu->cu->read_in_chain = dwarf2_per_objfile->read_in_chain;
+      dwarf2_per_objfile->read_in_chain = item->per_cu;
+
+      /* If this compilation unit has already had full symbols created,
+        reset the TYPE fields in each DIE.  */
+      if (item->per_cu->psymtab->readin)
+       reset_die_and_siblings_types (item->per_cu->cu->dies,
+                                     item->per_cu->cu);
+    }
+
+  /* Now everything left on the queue needs to be read in.  Process
+     them, one at a time, removing from the queue as we finish.  */
+  for (item = dwarf2_queue; item != NULL; dwarf2_queue = item = next_item)
+    {
+      if (!item->per_cu->psymtab->readin)
+       process_full_comp_unit (item->per_cu);
+
+      item->per_cu->queued = 0;
+      next_item = item->next;
+      xfree (item);
+    }
+
+  dwarf2_queue_tail = NULL;
+}
+
+/* Free all allocated queue entries.  This function only releases anything if
+   an error was thrown; if the queue was processed then it would have been
+   freed as we went along.  */
+
+static void
+dwarf2_release_queue (void *dummy)
+{
+  struct dwarf2_queue_item *item, *last;
+
+  item = dwarf2_queue;
+  while (item)
+    {
+      /* Anything still marked queued is likely to be in an
+        inconsistent state, so discard it.  */
+      if (item->per_cu->queued)
+       {
+         if (item->per_cu->cu != NULL)
+           free_one_cached_comp_unit (item->per_cu->cu);
+         item->per_cu->queued = 0;
        }
+
+      last = item;
+      item = item->next;
+      xfree (last);
     }
+
+  dwarf2_queue = dwarf2_queue_tail = NULL;
 }
 
+/* Read in full symbols for PST, and anything it depends on.  */
+
 static void
 psymtab_to_symtab_1 (struct partial_symtab *pst)
 {
-  struct objfile *objfile = pst->objfile;
-  bfd *abfd = objfile->obfd;
-  struct dwarf2_cu cu;
-  struct die_info *dies;
-  unsigned long offset;
-  CORE_ADDR lowpc, highpc;
-  struct die_info *child_die;
-  char *info_ptr;
-  struct symtab *symtab;
+  struct dwarf2_per_cu_data *per_cu;
   struct cleanup *back_to;
-  struct attribute *attr;
-  CORE_ADDR baseaddr;
   int i;
 
   for (i = 0; i < pst->number_of_dependencies; i++)
@@ -2098,6 +2448,7 @@ psymtab_to_symtab_1 (struct partial_symtab *pst)
         /* Inform about additional files that need to be read in.  */
         if (info_verbose)
           {
+           /* FIXME: i18n: Need to make this a single string.  */
             fputs_filtered (" ", gdb_stdout);
             wrap_here ("");
             fputs_filtered ("and ", gdb_stdout);
@@ -2109,7 +2460,9 @@ psymtab_to_symtab_1 (struct partial_symtab *pst)
         psymtab_to_symtab_1 (pst->dependencies[i]);
       }
 
-  if (PST_PRIVATE (pst) == NULL)
+  per_cu = (struct dwarf2_per_cu_data *) pst->read_symtab_private;
+
+  if (per_cu == NULL)
     {
       /* It's an include file, no symbols to read for it.
          Everything is in the parent symtab.  */
@@ -2117,39 +2470,107 @@ psymtab_to_symtab_1 (struct partial_symtab *pst)
       return;
     }
 
-  dwarf2_per_objfile = objfile_data (pst->objfile, dwarf2_objfile_data_key);
+  back_to = make_cleanup (dwarf2_release_queue, NULL);
+
+  queue_comp_unit (per_cu);
+
+  process_queue (pst->objfile);
+
+  /* Age the cache, releasing compilation units that have not
+     been used recently.  */
+  age_cached_comp_units ();
+
+  do_cleanups (back_to);
+}
+
+/* Load the DIEs associated with PST and PER_CU into memory.  */
+
+static struct dwarf2_cu *
+load_full_comp_unit (struct dwarf2_per_cu_data *per_cu)
+{
+  struct partial_symtab *pst = per_cu->psymtab;
+  bfd *abfd = pst->objfile->obfd;
+  struct dwarf2_cu *cu;
+  unsigned long offset;
+  char *info_ptr;
+  struct cleanup *back_to, *free_cu_cleanup;
+  struct attribute *attr;
+  CORE_ADDR baseaddr;
 
   /* Set local variables from the partial symbol table info.  */
-  offset = DWARF_INFO_OFFSET (pst);
+  offset = per_cu->offset;
 
   info_ptr = dwarf2_per_objfile->info_buffer + offset;
-  baseaddr = ANOFFSET (objfile->section_offsets, SECT_OFF_TEXT (objfile));
-
-  /* We're in the global namespace.  */
-  processing_current_prefix = "";
 
-  obstack_init (&cu.comp_unit_obstack);
-  back_to = make_cleanup (free_stack_comp_unit, &cu);
+  cu = xmalloc (sizeof (struct dwarf2_cu));
+  memset (cu, 0, sizeof (struct dwarf2_cu));
 
-  buildsym_init ();
-  make_cleanup (really_free_pendings, NULL);
+  /* If an error occurs while loading, release our storage.  */
+  free_cu_cleanup = make_cleanup (free_one_comp_unit, cu);
 
-  cu.objfile = objfile;
+  cu->objfile = pst->objfile;
 
   /* read in the comp_unit header  */
-  info_ptr = read_comp_unit_head (&cu.header, info_ptr, abfd);
+  info_ptr = read_comp_unit_head (&cu->header, info_ptr, abfd);
 
   /* Read the abbrevs for this compilation unit  */
-  dwarf2_read_abbrevs (abfd, &cu);
-  make_cleanup (dwarf2_free_abbrev_table, &cu);
+  dwarf2_read_abbrevs (abfd, cu);
+  back_to = make_cleanup (dwarf2_free_abbrev_table, cu);
+
+  cu->header.offset = offset;
+
+  cu->per_cu = per_cu;
+  per_cu->cu = cu;
+
+  /* We use this obstack for block values in dwarf_alloc_block.  */
+  obstack_init (&cu->comp_unit_obstack);
+
+  cu->dies = read_comp_unit (info_ptr, abfd, cu);
+
+  /* We try not to read any attributes in this function, because not
+     all objfiles needed for references have been loaded yet, and symbol
+     table processing isn't initialized.  But we have to set the CU language,
+     or we won't be able to build types correctly.  */
+  attr = dwarf2_attr (cu->dies, DW_AT_language, cu);
+  if (attr)
+    set_cu_language (DW_UNSND (attr), cu);
+  else
+    set_cu_language (language_minimal, cu);
+
+  do_cleanups (back_to);
+
+  /* We've successfully allocated this compilation unit.  Let our caller
+     clean it up when finished with it.  */
+  discard_cleanups (free_cu_cleanup);
+
+  return cu;
+}
+
+/* Generate full symbol information for PST and CU, whose DIEs have
+   already been loaded into memory.  */
+
+static void
+process_full_comp_unit (struct dwarf2_per_cu_data *per_cu)
+{
+  struct partial_symtab *pst = per_cu->psymtab;
+  struct dwarf2_cu *cu = per_cu->cu;
+  struct objfile *objfile = pst->objfile;
+  bfd *abfd = objfile->obfd;
+  CORE_ADDR lowpc, highpc;
+  struct symtab *symtab;
+  struct cleanup *back_to;
+  struct attribute *attr;
+  CORE_ADDR baseaddr;
 
-  cu.header.offset = offset;
+  baseaddr = ANOFFSET (objfile->section_offsets, SECT_OFF_TEXT (objfile));
 
-  cu.list_in_scope = &file_symbols;
+  /* We're in the global namespace.  */
+  processing_current_prefix = "";
 
-  dies = read_comp_unit (info_ptr, abfd, &cu);
+  buildsym_init ();
+  back_to = make_cleanup (really_free_pendings, NULL);
 
-  make_cleanup_free_die_list (dies);
+  cu->list_in_scope = &file_symbols;
 
   /* Find the base address of the compilation unit for range lists and
      location lists.  It will normally be specified by DW_AT_low_pc.
@@ -2157,32 +2578,32 @@ psymtab_to_symtab_1 (struct partial_symtab *pst)
      DW_AT_entry_pc.  It's been removed, but GCC still uses this for
      compilation units with discontinuous ranges.  */
 
-  cu.header.base_known = 0;
-  cu.header.base_address = 0;
+  cu->header.base_known = 0;
+  cu->header.base_address = 0;
 
-  attr = dwarf2_attr (dies, DW_AT_entry_pc, &cu);
+  attr = dwarf2_attr (cu->dies, DW_AT_entry_pc, cu);
   if (attr)
     {
-      cu.header.base_address = DW_ADDR (attr);
-      cu.header.base_known = 1;
+      cu->header.base_address = DW_ADDR (attr);
+      cu->header.base_known = 1;
     }
   else
     {
-      attr = dwarf2_attr (dies, DW_AT_low_pc, &cu);
+      attr = dwarf2_attr (cu->dies, DW_AT_low_pc, cu);
       if (attr)
        {
-         cu.header.base_address = DW_ADDR (attr);
-         cu.header.base_known = 1;
+         cu->header.base_address = DW_ADDR (attr);
+         cu->header.base_known = 1;
        }
     }
 
   /* Do line number decoding in read_file_scope () */
-  process_die (dies, &cu);
+  process_die (cu->dies, cu);
 
   /* 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.  */
-  get_scope_pc_bounds (dies, &lowpc, &highpc, &cu);
+  get_scope_pc_bounds (cu->dies, &lowpc, &highpc, cu);
 
   symtab = end_symtab (highpc + baseaddr, objfile, SECT_OFF_TEXT (objfile));
 
@@ -2190,9 +2611,9 @@ psymtab_to_symtab_1 (struct partial_symtab *pst)
      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))
+      && !(cu->language == language_c && symtab->language != language_c))
     {
-      symtab->language = cu.language;
+      symtab->language = cu->language;
     }
   pst->symtab = symtab;
   pst->readin = 1;
@@ -2351,19 +2772,16 @@ read_file_scope (struct die_info *die, struct dwarf2_cu *cu)
        }
     }
 
-  if (objfile->ei.entry_point >= lowpc &&
-      objfile->ei.entry_point < highpc)
-    {
-      objfile->ei.deprecated_entry_file_lowpc = lowpc;
-      objfile->ei.deprecated_entry_file_highpc = highpc;
-    }
-
   attr = dwarf2_attr (die, DW_AT_language, cu);
   if (attr)
     {
       set_cu_language (DW_UNSND (attr), cu);
     }
 
+  attr = dwarf2_attr (die, DW_AT_producer, cu);
+  if (attr) 
+    cu->producer = DW_STRING (attr);
+  
   /* We assume that we're processing GCC output. */
   processing_gcc_compilation = 2;
 #if 0
@@ -2467,7 +2885,8 @@ read_func_scope (struct die_info *die, struct dwarf2_cu *cu)
   if (name == NULL || !dwarf2_get_pc_bounds (die, &lowpc, &highpc, cu))
     return;
 
-  if (cu->language == language_cplus)
+  if (cu->language == language_cplus
+      || cu->language == language_java)
     {
       struct die_info *spec_die = die_specification (die, cu);
 
@@ -2507,13 +2926,6 @@ read_func_scope (struct die_info *die, struct dwarf2_cu *cu)
   /* Record the function range for dwarf_decode_lines.  */
   add_to_cu_func_list (name, lowpc, highpc, cu);
 
-  if (objfile->ei.entry_point >= lowpc &&
-      objfile->ei.entry_point < highpc)
-    {
-      objfile->ei.entry_func_lowpc = lowpc;
-      objfile->ei.entry_func_highpc = highpc;
-    }
-
   new = push_context (0, lowpc);
   new->name = new_symbol (die, die->type, cu);
 
@@ -2663,7 +3075,7 @@ dwarf2_get_pc_bounds (struct die_info *die, CORE_ADDR *lowpc,
          if (offset >= dwarf2_per_objfile->ranges_size)
            {
              complaint (&symfile_complaints,
-                        "Offset %d out of bounds for DW_AT_ranges attribute",
+                        _("Offset %d out of bounds for DW_AT_ranges attribute"),
                         offset);
              return 0;
            }
@@ -2715,7 +3127,7 @@ dwarf2_get_pc_bounds (struct die_info *die, CORE_ADDR *lowpc,
                  /* We have no valid base address for the ranges
                     data.  */
                  complaint (&symfile_complaints,
-                            "Invalid .debug_ranges data (no base address)");
+                            _("Invalid .debug_ranges data (no base address)"));
                  return 0;
                }
 
@@ -3071,7 +3483,7 @@ dwarf2_attach_fields_to_type (struct field_info *fip, struct type *type,
        default:
          /* Unknown accessibility.  Complain and treat it as public.  */
          {
-           complaint (&symfile_complaints, "unsupported accessibility %d",
+           complaint (&symfile_complaints, _("unsupported accessibility %d"),
                       fip->fields->accessibility);
          }
          break;
@@ -3180,7 +3592,7 @@ dwarf2_add_member_fn (struct field_info *fip, struct die_info *die,
        fnp->voffset = VOFFSET_STATIC;
     }
   else
-    complaint (&symfile_complaints, "member function type missing for '%s'",
+    complaint (&symfile_complaints, _("member function type missing for '%s'"),
               physname);
 
   /* Get fcontext from DW_AT_containing_type if present.  */
@@ -3265,6 +3677,26 @@ dwarf2_attach_fn_fields_to_type (struct field_info *fip, struct type *type,
   TYPE_NFN_FIELDS_TOTAL (type) = total_length;
 }
 
+
+/* Returns non-zero if NAME is the name of a vtable member in CU's
+   language, zero otherwise.  */
+static int
+is_vtable_name (const char *name, struct dwarf2_cu *cu)
+{
+  static const char vptr[] = "_vptr";
+  static const char vtable[] = "vtable";
+
+  /* Look for the C++ and Java forms of the vtable.  */
+  if ((cu->language == language_java
+       && strncmp (name, vtable, sizeof (vtable) - 1) == 0)
+       || (strncmp (name, vptr, sizeof (vptr) - 1) == 0
+       && is_cplus_marker (name[sizeof (vptr) - 1])))
+    return 1;
+
+  return 0;
+}
+
+
 /* 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.
@@ -3299,7 +3731,8 @@ read_structure_type (struct die_info *die, struct dwarf2_cu *cu)
   attr = dwarf2_attr (die, DW_AT_name, cu);
   if (attr && DW_STRING (attr))
     {
-      if (cu->language == language_cplus)
+      if (cu->language == language_cplus
+         || cu->language == language_java)
        {
          char *new_prefix = determine_class_name (die, cu);
          TYPE_TAG_NAME (type) = obsavestring (new_prefix,
@@ -3347,7 +3780,7 @@ read_structure_type (struct die_info *die, struct dwarf2_cu *cu)
   /* 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;
+  set_die_type (die, type, cu);
 
   if (die->child != NULL && ! die_is_declaration (die, cu))
     {
@@ -3403,8 +3836,6 @@ read_structure_type (struct die_info *die, struct dwarf2_cu *cu)
              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.  */
@@ -3414,10 +3845,7 @@ read_structure_type (struct die_info *die, struct dwarf2_cu *cu)
                    {
                      char *fieldname = TYPE_FIELD_NAME (t, i);
 
-                     if ((strncmp (fieldname, vptr_name,
-                                    strlen (vptr_name) - 1)
-                           == 0)
-                         && is_cplus_marker (fieldname[strlen (vptr_name)]))
+                      if (is_vtable_name (fieldname, cu))
                        {
                          TYPE_VPTR_FIELDNO (type) = i;
                          break;
@@ -3427,7 +3855,7 @@ read_structure_type (struct die_info *die, struct dwarf2_cu *cu)
                  /* Complain if virtual function table field not found.  */
                  if (i < TYPE_N_BASECLASSES (t))
                    complaint (&symfile_complaints,
-                              "virtual function table pointer not found when defining class '%s'",
+                              _("virtual function table pointer not found when defining class '%s'"),
                               TYPE_TAG_NAME (type) ? TYPE_TAG_NAME (type) :
                               "");
                }
@@ -3506,11 +3934,9 @@ read_enumeration_type (struct die_info *die, struct dwarf2_cu *cu)
 
       if (processing_has_namespace_info)
        {
-         TYPE_TAG_NAME (type) = obconcat (&objfile->objfile_obstack,
-                                          processing_current_prefix,
-                                          processing_current_prefix[0] == '\0'
-                                          ? "" : "::",
-                                          name);
+         TYPE_TAG_NAME (type) = typename_concat (&objfile->objfile_obstack,
+                                                 processing_current_prefix,
+                                                 name, cu);
        }
       else
        {
@@ -3530,11 +3956,11 @@ read_enumeration_type (struct die_info *die, struct dwarf2_cu *cu)
       TYPE_LENGTH (type) = 0;
     }
 
-  die->type = type;
+  set_die_type (die, type, cu);
 }
 
 /* Determine the name of the type represented by DIE, which should be
-   a named C++ compound type.  Return the name in question; the caller
+   a named C++ or Java compound type.  Return the name in question; the caller
    is responsible for xfree()'ing it.  */
 
 static char *
@@ -3567,7 +3993,9 @@ determine_class_name (struct die_info *die, struct dwarf2_cu *cu)
        {
          if (child->tag == DW_TAG_subprogram)
            {
-             new_prefix = class_name_from_physname (dwarf2_linkage_name
+             new_prefix 
+               = language_class_name_from_physname (cu->language_defn,
+                                                    dwarf2_linkage_name
                                                     (child, cu));
 
              if (new_prefix != NULL)
@@ -3579,8 +4007,9 @@ determine_class_name (struct die_info *die, struct dwarf2_cu *cu)
   if (new_prefix == NULL)
     {
       const char *name = dwarf2_name (die, cu);
-      new_prefix = typename_concat (processing_current_prefix,
-                                   name ? name : "<<anonymous>>");
+      new_prefix = typename_concat (NULL, processing_current_prefix,
+                                   name ? name : "<<anonymous>>", 
+                                   cu);
     }
 
   if (back_to != NULL)
@@ -3693,7 +4122,8 @@ read_array_type (struct die_info *die, struct dwarf2_cu *cu)
     {
       index_type = dwarf2_fundamental_type (objfile, FT_INTEGER, cu);
       range_type = create_range_type (NULL, index_type, 0, -1);
-      die->type = create_array_type (NULL, element_type, range_type);
+      set_die_type (die, create_array_type (NULL, element_type, range_type),
+                   cu);
       return;
     }
 
@@ -3725,11 +4155,22 @@ read_array_type (struct die_info *die, struct dwarf2_cu *cu)
 
   /* 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
+  if (read_array_order (die, cu) == DW_ORD_col_major)
+    {
+      int i = 0;
+      while (i < ndim)
+       type = create_array_type (NULL, type, range_types[i++]);
+    }
+  else
+    {
+      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
@@ -3742,9 +4183,44 @@ read_array_type (struct die_info *die, struct dwarf2_cu *cu)
   do_cleanups (back_to);
 
   /* Install the type in the die. */
-  die->type = type;
+  set_die_type (die, type, cu);
+}
+
+static enum dwarf_array_dim_ordering
+read_array_order (struct die_info *die, struct dwarf2_cu *cu) 
+{
+  struct attribute *attr;
+
+  attr = dwarf2_attr (die, DW_AT_ordering, cu);
+
+  if (attr) return DW_SND (attr);
+
+  /*
+    GNU F77 is a special case, as at 08/2004 array type info is the
+    opposite order to the dwarf2 specification, but data is still 
+    laid out as per normal fortran.
+
+    FIXME: dsl/2004-8-20: If G77 is ever fixed, this will also need 
+    version checking.
+  */
+
+  if (cu->language == language_fortran &&
+      cu->producer && strstr (cu->producer, "GNU F77"))
+    {
+      return DW_ORD_row_major;
+    }
+
+  switch (cu->language_defn->la_array_ordering) 
+    {
+    case array_column_major:
+      return DW_ORD_col_major;
+    case array_row_major:
+    default:
+      return DW_ORD_row_major;
+    };
 }
 
+
 /* First cut: install each common block member as a global variable.  */
 
 static void
@@ -3801,6 +4277,7 @@ read_namespace (struct die_info *die, struct dwarf2_cu *cu)
   const char *name;
   int is_anonymous;
   struct die_info *current_die;
+  struct cleanup *back_to = make_cleanup (null_cleanup, 0);
 
   name = namespace_name (die, &is_anonymous, cu);
 
@@ -3812,14 +4289,8 @@ read_namespace (struct die_info *die, struct dwarf2_cu *cu)
     }
   else
     {
-      /* We need temp_name around because processing_current_prefix
-        is a const char *.  */
-      char *temp_name = alloca (strlen (previous_prefix)
-                               + 2 + strlen(name) + 1);
-      strcpy (temp_name, previous_prefix);
-      strcat (temp_name, "::");
-      strcat (temp_name, name);
-
+      char *temp_name = typename_concat (NULL, previous_prefix, name, cu);
+      make_cleanup (xfree, temp_name);
       processing_current_prefix = temp_name;
     }
 
@@ -3839,7 +4310,7 @@ read_namespace (struct die_info *die, struct dwarf2_cu *cu)
       TYPE_TAG_NAME (type) = TYPE_NAME (type);
 
       new_symbol (die, type, cu);
-      die->type = type;
+      set_die_type (die, type, cu);
 
       if (is_anonymous)
        cp_add_using_directive (processing_current_prefix,
@@ -3859,6 +4330,7 @@ read_namespace (struct die_info *die, struct dwarf2_cu *cu)
     }
 
   processing_current_prefix = previous_prefix;
+  do_cleanups (back_to);
 }
 
 /* Return the name of the namespace represented by DIE.  Set
@@ -3937,7 +4409,7 @@ read_tag_pointer_type (struct die_info *die, struct dwarf2_cu *cu)
        }
       else if (TYPE_LENGTH (type) != byte_size)
        {
-         complaint (&symfile_complaints, "invalid pointer size %d", byte_size);
+         complaint (&symfile_complaints, _("invalid pointer size %d"), byte_size);
        }
       else {
        /* Should we also complain about unhandled address classes?  */
@@ -3945,7 +4417,7 @@ read_tag_pointer_type (struct die_info *die, struct dwarf2_cu *cu)
     }
 
   TYPE_LENGTH (type) = byte_size;
-  die->type = type;
+  set_die_type (die, type, cu);
 }
 
 /* Extract all information from a DW_TAG_ptr_to_member_type DIE and add to
@@ -3969,7 +4441,7 @@ read_tag_ptr_to_member_type (struct die_info *die, struct dwarf2_cu *cu)
   domain = die_containing_type (die, cu);
   smash_to_member_type (type, domain, to_type);
 
-  die->type = type;
+  set_die_type (die, type, cu);
 }
 
 /* Extract all information from a DW_TAG_reference_type DIE and add to
@@ -3997,7 +4469,7 @@ read_tag_reference_type (struct die_info *die, struct dwarf2_cu *cu)
     {
       TYPE_LENGTH (type) = cu_header->addr_size;
     }
-  die->type = type;
+  set_die_type (die, type, cu);
 }
 
 static void
@@ -4011,7 +4483,8 @@ read_tag_const_type (struct die_info *die, struct dwarf2_cu *cu)
     }
 
   base_type = die_type (die, cu);
-  die->type = make_cv_type (1, TYPE_VOLATILE (base_type), base_type, 0);
+  set_die_type (die, make_cv_type (1, TYPE_VOLATILE (base_type), base_type, 0),
+               cu);
 }
 
 static void
@@ -4025,7 +4498,8 @@ read_tag_volatile_type (struct die_info *die, struct dwarf2_cu *cu)
     }
 
   base_type = die_type (die, cu);
-  die->type = make_cv_type (TYPE_CONST (base_type), 1, base_type, 0);
+  set_die_type (die, make_cv_type (TYPE_CONST (base_type), 1, base_type, 0),
+               cu);
 }
 
 /* Extract all information from a DW_TAG_string_type DIE and add to
@@ -4077,7 +4551,7 @@ read_tag_string_type (struct die_info *die, struct dwarf2_cu *cu)
       char_type = dwarf2_fundamental_type (objfile, FT_CHAR, cu);
       type = create_string_type (char_type, range_type);
     }
-  die->type = type;
+  set_die_type (die, type, cu);
 }
 
 /* Handle DIES due to C code like:
@@ -4104,12 +4578,13 @@ read_subroutine_type (struct die_info *die, struct dwarf2_cu *cu)
       return;
     }
   type = die_type (die, cu);
-  ftype = lookup_function_type (type);
+  ftype = make_function_type (type, (struct type **) 0);
 
-  /* All functions in C++ have prototypes.  */
+  /* All functions in C++ and Java have prototypes.  */
   attr = dwarf2_attr (die, DW_AT_prototyped, cu);
   if ((attr && (DW_UNSND (attr) != 0))
-      || cu->language == language_cplus)
+      || cu->language == language_cplus
+      || cu->language == language_java)
     TYPE_FLAGS (ftype) |= TYPE_FLAG_PROTOTYPED;
 
   if (die->child != NULL)
@@ -4158,7 +4633,7 @@ read_subroutine_type (struct die_info *die, struct dwarf2_cu *cu)
        }
     }
 
-  die->type = ftype;
+  set_die_type (die, ftype, cu);
 }
 
 static void
@@ -4175,7 +4650,9 @@ read_typedef (struct die_info *die, struct dwarf2_cu *cu)
        {
          name = DW_STRING (attr);
        }
-      die->type = init_type (TYPE_CODE_TYPEDEF, 0, TYPE_FLAG_TARGET_STUB, name, objfile);
+      set_die_type (die, init_type (TYPE_CODE_TYPEDEF, 0,
+                                   TYPE_FLAG_TARGET_STUB, name, objfile),
+                   cu);
       TYPE_TARGET_TYPE (die->type) = die_type (die, cu);
     }
 }
@@ -4238,7 +4715,7 @@ read_base_type (struct die_info *die, struct dwarf2_cu *cu)
          type_flags |= TYPE_FLAG_UNSIGNED;
          break;
        default:
-         complaint (&symfile_complaints, "unsupported DW_AT_encoding: '%s'",
+         complaint (&symfile_complaints, _("unsupported DW_AT_encoding: '%s'"),
                     dwarf_type_encoding_name (encoding));
          break;
        }
@@ -4263,7 +4740,7 @@ read_base_type (struct die_info *die, struct dwarf2_cu *cu)
     {
       type = dwarf_base_type (encoding, size, cu);
     }
-  die->type = type;
+  set_die_type (die, type, cu);
 }
 
 /* Read the given DW_AT_subrange DIE.  */
@@ -4285,7 +4762,7 @@ read_subrange_type (struct die_info *die, struct dwarf2_cu *cu)
   if (base_type == NULL)
     {
       complaint (&symfile_complaints,
-                "DW_AT_type missing from DW_TAG_subrange_type");
+                _("DW_AT_type missing from DW_TAG_subrange_type"));
       return;
     }
 
@@ -4298,6 +4775,9 @@ read_subrange_type (struct die_info *die, struct dwarf2_cu *cu)
       low = 1;
     }
 
+  /* FIXME: For variable sized arrays either of these could be
+     a variable rather than a constant value.  We'll allow it,
+     but we don't know how to handle it.  */
   attr = dwarf2_attr (die, DW_AT_lower_bound, cu);
   if (attr)
     low = dwarf2_get_attr_constant_value (attr, 0);
@@ -4334,7 +4814,7 @@ read_subrange_type (struct die_info *die, struct dwarf2_cu *cu)
   if (attr)
     TYPE_LENGTH (range_type) = DW_UNSND (attr);
 
-  die->type = range_type;
+  set_die_type (die, range_type, cu);
 }
   
 
@@ -4343,10 +4823,6 @@ read_subrange_type (struct die_info *die, struct dwarf2_cu *cu)
 static struct die_info *
 read_comp_unit (char *info_ptr, bfd *abfd, struct dwarf2_cu *cu)
 {
-  /* Reset die reference table; we are
-     building new ones now.  */
-  dwarf2_empty_hash_tables ();
-
   return read_die_and_children (info_ptr, abfd, cu, &info_ptr, NULL);
 }
 
@@ -4367,7 +4843,7 @@ read_die_and_children (char *info_ptr, bfd *abfd,
   int has_children;
 
   cur_ptr = read_full_die (&die, abfd, info_ptr, cu, &has_children);
-  store_in_ref_table (die->offset, die);
+  store_in_ref_table (die->offset, die, cu);
 
   if (has_children)
     {
@@ -4446,19 +4922,6 @@ free_die_list (struct die_info *dies)
     }
 }
 
-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 objfile_obstack and return it.  */
 
@@ -4467,7 +4930,7 @@ dwarf2_read_section (struct objfile *objfile, asection *sectp)
 {
   bfd *abfd = objfile->obfd;
   char *buf, *retbuf;
-  bfd_size_type size = bfd_get_section_size_before_reloc (sectp);
+  bfd_size_type size = bfd_get_section_size (sectp);
 
   if (size == 0)
     return NULL;
@@ -4480,7 +4943,7 @@ dwarf2_read_section (struct objfile *objfile, asection *sectp)
 
   if (bfd_seek (abfd, sectp->filepos, SEEK_SET) != 0
       || bfd_bread (buf, size, abfd) != size)
-    error ("Dwarf Error: Can't read DWARF data from '%s'",
+    error (_("Dwarf Error: Can't read DWARF data from '%s'"),
           bfd_get_filename (abfd));
 
   return buf;
@@ -4547,6 +5010,17 @@ dwarf2_read_abbrevs (bfd *abfd, struct dwarf2_cu *cu)
                = xrealloc (cur_attrs, (allocated_attrs
                                        * sizeof (struct attr_abbrev)));
            }
+
+         /* Record whether this compilation unit might have
+            inter-compilation-unit references.  If we don't know what form
+            this attribute will have, then it might potentially be a
+            DW_FORM_ref_addr, so we conservatively expect inter-CU
+            references.  */
+
+         if (abbrev_form == DW_FORM_ref_addr
+             || abbrev_form == DW_FORM_indirect)
+           cu->has_form_ref_addr = 1;
+
          cur_attrs[cur_abbrev->num_attrs].name = abbrev_name;
          cur_attrs[cur_abbrev->num_attrs++].form = abbrev_form;
          abbrev_name = read_unsigned_leb128 (abfd, abbrev_ptr, &bytes_read);
@@ -4756,11 +5230,12 @@ load_partial_dies (bfd *abfd, char *info_ptr, int building_psymtab,
          && parent_die->has_specification == 0)
        {
          if (part_die->name == NULL)
-           complaint (&symfile_complaints, "malformed enumerator DIE ignored");
+           complaint (&symfile_complaints, _("malformed enumerator DIE ignored"));
          else if (building_psymtab)
            add_psymbol_to_list (part_die->name, strlen (part_die->name),
                                 VAR_DOMAIN, LOC_CONST,
-                                cu->language == language_cplus
+                                (cu->language == language_cplus
+                                 || cu->language == language_java)
                                 ? &cu->objfile->global_psymbols
                                 : &cu->objfile->static_psymbols,
                                 0, (CORE_ADDR) 0, cu->language, cu->objfile);
@@ -4882,6 +5357,10 @@ read_partial_die (struct partial_die_info *part_die,
          if (part_die->name == NULL)
            part_die->name = DW_STRING (&attr);
          break;
+       case DW_AT_comp_dir:
+         if (part_die->dirname == NULL)
+           part_die->dirname = DW_STRING (&attr);
+         break;
        case DW_AT_MIPS_linkage_name:
          part_die->name = DW_STRING (&attr);
          break;
@@ -4931,7 +5410,7 @@ read_partial_die (struct partial_die_info *part_die,
          /* Ignore absolute siblings, they might point outside of
             the current compile unit.  */
          if (attr.form == DW_FORM_ref_addr)
-           complaint (&symfile_complaints, "ignoring absolute DW_AT_sibling");
+           complaint (&symfile_complaints, _("ignoring absolute DW_AT_sibling"));
          else
            part_die->sibling = dwarf2_per_objfile->info_buffer
              + dwarf2_get_ref_die_offset (&attr, cu);
@@ -4974,7 +5453,7 @@ find_partial_die_in_comp_unit (unsigned long offset, struct dwarf2_cu *cu)
 
   if (lookup_die == NULL)
     internal_error (__FILE__, __LINE__,
-                   "could not find partial DIE in cache\n");
+                   _("could not find partial DIE in cache\n"));
 
   return lookup_die;
 }
@@ -4982,20 +5461,25 @@ find_partial_die_in_comp_unit (unsigned long offset, struct dwarf2_cu *cu)
 /* Find a partial DIE at OFFSET, which may or may not be in CU.  */
 
 static struct partial_die_info *
-find_partial_die (unsigned long offset, struct dwarf2_cu *cu,
-                 struct dwarf2_cu **target_cu)
+find_partial_die (unsigned long offset, struct dwarf2_cu *cu)
 {
   struct dwarf2_per_cu_data *per_cu;
 
   if (offset >= cu->header.offset
       && offset < cu->header.offset + cu->header.length)
+    return find_partial_die_in_comp_unit (offset, cu);
+
+  per_cu = dwarf2_find_containing_comp_unit (offset, cu->objfile);
+
+  if (per_cu->cu == NULL)
     {
-      *target_cu = cu;
-      return find_partial_die_in_comp_unit (offset, cu);
+      load_comp_unit (per_cu, cu->objfile);
+      per_cu->cu->read_in_chain = dwarf2_per_objfile->read_in_chain;
+      dwarf2_per_objfile->read_in_chain = per_cu;
     }
 
-  internal_error (__FILE__, __LINE__,
-                 "unsupported inter-compilation-unit reference");
+  per_cu->cu->last_used = 0;
+  return find_partial_die_in_comp_unit (offset, per_cu->cu);
 }
 
 /* Adjust PART_DIE before generating a symbol for it.  This function
@@ -5011,11 +5495,10 @@ fixup_partial_die (struct partial_die_info *part_die,
   if (part_die->name == NULL && part_die->has_specification)
     {
       struct partial_die_info *spec_die;
-      struct dwarf2_cu *spec_cu;
 
-      spec_die = find_partial_die (part_die->spec_offset, cu, &spec_cu);
+      spec_die = find_partial_die (part_die->spec_offset, cu);
 
-      fixup_partial_die (spec_die, spec_cu);
+      fixup_partial_die (spec_die, cu);
 
       if (spec_die->name)
        {
@@ -5071,7 +5554,7 @@ read_full_die (struct die_info **diep, bfd *abfd, char *info_ptr,
   abbrev = dwarf2_lookup_abbrev (abbrev_number, cu);
   if (!abbrev)
     {
-      error ("Dwarf Error: could not find abbrev number %d [in module %s]",
+      error (_("Dwarf Error: could not find abbrev number %d [in module %s]"),
             abbrev_number,
             bfd_get_filename (abfd));
     }
@@ -5089,6 +5572,38 @@ read_full_die (struct die_info **diep, bfd *abfd, char *info_ptr,
     {
       info_ptr = read_attribute (&die->attrs[i], &abbrev->attrs[i],
                                 abfd, info_ptr, cu);
+
+      /* If this attribute is an absolute reference to a different
+        compilation unit, make sure that compilation unit is loaded
+        also.  */
+      if (die->attrs[i].form == DW_FORM_ref_addr
+         && (DW_ADDR (&die->attrs[i]) < cu->header.offset
+             || (DW_ADDR (&die->attrs[i])
+                 >= cu->header.offset + cu->header.length)))
+       {
+         struct dwarf2_per_cu_data *per_cu;
+         per_cu = dwarf2_find_containing_comp_unit (DW_ADDR (&die->attrs[i]),
+                                                    cu->objfile);
+
+         /* Mark the dependence relation so that we don't flush PER_CU
+            too early.  */
+         dwarf2_add_dependence (cu, per_cu);
+
+         /* If it's already on the queue, we have nothing to do.  */
+         if (per_cu->queued)
+           continue;
+
+         /* If the compilation unit is already loaded, just mark it as
+            used.  */
+         if (per_cu->cu != NULL)
+           {
+             per_cu->cu->last_used = 0;
+             continue;
+           }
+
+         /* Add it to the queue.  */
+         queue_comp_unit (per_cu);
+       }
     }
 
   *diep = die;
@@ -5185,23 +5700,24 @@ read_attribute_value (struct attribute *attr, unsigned form,
       info_ptr += bytes_read;
       break;
     case DW_FORM_ref1:
-      DW_UNSND (attr) = read_1_byte (abfd, info_ptr);
+      DW_ADDR (attr) = cu->header.offset + read_1_byte (abfd, info_ptr);
       info_ptr += 1;
       break;
     case DW_FORM_ref2:
-      DW_UNSND (attr) = read_2_bytes (abfd, info_ptr);
+      DW_ADDR (attr) = cu->header.offset + read_2_bytes (abfd, info_ptr);
       info_ptr += 2;
       break;
     case DW_FORM_ref4:
-      DW_UNSND (attr) = read_4_bytes (abfd, info_ptr);
+      DW_ADDR (attr) = cu->header.offset + read_4_bytes (abfd, info_ptr);
       info_ptr += 4;
       break;
     case DW_FORM_ref8:
-      DW_UNSND (attr) = read_8_bytes (abfd, info_ptr);
+      DW_ADDR (attr) = cu->header.offset + 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);
+      DW_ADDR (attr) = (cu->header.offset
+                       + read_unsigned_leb128 (abfd, info_ptr, &bytes_read));
       info_ptr += bytes_read;
       break;
     case DW_FORM_indirect:
@@ -5210,7 +5726,7 @@ read_attribute_value (struct attribute *attr, unsigned form,
       info_ptr = read_attribute_value (attr, form, abfd, info_ptr, cu);
       break;
     default:
-      error ("Dwarf Error: Cannot handle %s in DWARF reader [in module %s]",
+      error (_("Dwarf Error: Cannot handle %s in DWARF reader [in module %s]"),
             dwarf_form_name (form),
             bfd_get_filename (abfd));
     }
@@ -5292,7 +5808,7 @@ read_address (bfd *abfd, char *buf, struct dwarf2_cu *cu, int *bytes_read)
          break;
        default:
          internal_error (__FILE__, __LINE__,
-                         "read_address: bad switch, signed [in module %s]",
+                         _("read_address: bad switch, signed [in module %s]"),
                          bfd_get_filename (abfd));
        }
     }
@@ -5311,7 +5827,7 @@ read_address (bfd *abfd, char *buf, struct dwarf2_cu *cu, int *bytes_read)
          break;
        default:
          internal_error (__FILE__, __LINE__,
-                         "read_address: bad switch, unsigned [in module %s]",
+                         _("read_address: bad switch, unsigned [in module %s]"),
                          bfd_get_filename (abfd));
        }
     }
@@ -5334,18 +5850,18 @@ read_address (bfd *abfd, char *buf, struct dwarf2_cu *cu, int *bytes_read)
    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.
+   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().
+   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().)
+   the width of file offsets to be fetched later with read_offset().)
    
    [ Note:  read_initial_length() and read_offset() are based on the
      document entitled "DWARF Debugging Information Format", revision
@@ -5357,8 +5873,8 @@ read_address (bfd *abfd, char *buf, struct dwarf2_cu *cu, int *bytes_read)
      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.
+     determined empirically by examining 64-bit ELF files produced by
+     the SGI toolchain on an IRIX 6.5 machine.
 
      - Kevin, July 16, 2002
    ] */
@@ -5367,47 +5883,45 @@ static LONGEST
 read_initial_length (bfd *abfd, char *buf, struct comp_unit_head *cu_header,
                      int *bytes_read)
 {
-  LONGEST retval = 0;
+  LONGEST length = bfd_get_32 (abfd, (bfd_byte *) buf);
 
-  retval = bfd_get_32 (abfd, (bfd_byte *) buf);
-
-  if (retval == 0xffffffff)
+  if (length == 0xffffffff)
     {
-      retval = bfd_get_64 (abfd, (bfd_byte *) buf + 4);
+      length = 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)
+  else if (length == 0)
     {
-      /* Handle (non-standard) 64-bit DWARF2 formats such as that used
-         by IRIX.  */
-      retval = bfd_get_64 (abfd, (bfd_byte *) buf);
+      /* Handle the (non-standard) 64-bit DWARF2 format used by IRIX.  */
+      length = 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;
+  if (cu_header)
+    {
+      gdb_assert (cu_header->initial_length_size == 0
+                 || cu_header->initial_length_size == 4
+                 || cu_header->initial_length_size == 8
+                 || cu_header->initial_length_size == 12);
+
+      if (cu_header->initial_length_size != 0
+         && cu_header->initial_length_size != *bytes_read)
+       complaint (&symfile_complaints,
+                  _("intermixed 32-bit and 64-bit DWARF sections"));
+
+      cu_header->initial_length_size = *bytes_read;
+      cu_header->offset_size = (*bytes_read == 4) ? 4 : 8;
+    }
+
+  return length;
 }
 
 /* Read an offset from the data stream.  The size of the offset is
-   given by cu_header->offset_size. */
+   given by cu_header->offset_size.  */
 
 static LONGEST
 read_offset (bfd *abfd, char *buf, const struct comp_unit_head *cu_header,
@@ -5427,11 +5941,11 @@ read_offset (bfd *abfd, char *buf, const struct comp_unit_head *cu_header,
       break;
     default:
       internal_error (__FILE__, __LINE__,
-                     "read_offset: bad switch [in module %s]",
+                     _("read_offset: bad switch [in module %s]"),
                      bfd_get_filename (abfd));
     }
 
- return retval;
 return retval;
 }
 
 static char *
@@ -5470,13 +5984,13 @@ read_indirect_string (bfd *abfd, char *buf,
 
   if (dwarf2_per_objfile->str_buffer == NULL)
     {
-      error ("DW_FORM_strp used without .debug_str section [in module %s]",
+      error (_("DW_FORM_strp used without .debug_str section [in module %s]"),
                      bfd_get_filename (abfd));
       return NULL;
     }
   if (str_offset >= dwarf2_per_objfile->str_size)
     {
-      error ("DW_FORM_strp pointing outside of .debug_str section [in module %s]",
+      error (_("DW_FORM_strp pointing outside of .debug_str section [in module %s]"),
                      bfd_get_filename (abfd));
       return NULL;
     }
@@ -5587,6 +6101,8 @@ set_cu_language (unsigned int lang, struct dwarf2_cu *cu)
       break;
     case DW_LANG_Ada83:
     case DW_LANG_Ada95:
+      cu->language = language_ada;
+      break;
     case DW_LANG_Cobol74:
     case DW_LANG_Cobol85:
     case DW_LANG_Pascal83:
@@ -5609,21 +6125,14 @@ dwarf2_attr (struct die_info *die, unsigned int name, struct dwarf2_cu *cu)
   for (i = 0; i < die->num_attrs; ++i)
     {
       if (die->attrs[i].name == name)
-       {
-         return &die->attrs[i];
-       }
+       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, cu));
 
-      if (ref_die)
-       return dwarf2_attr (ref_die, name, cu);
-    }
+  if (spec)
+    return dwarf2_attr (follow_die_ref (die, spec, cu), name, cu);
 
   return NULL;
 }
@@ -5665,7 +6174,7 @@ die_specification (struct die_info *die, struct dwarf2_cu *cu)
   if (spec_attr == NULL)
     return NULL;
   else
-    return follow_die_ref (dwarf2_get_ref_die_offset (spec_attr, cu));
+    return follow_die_ref (die, spec_attr, cu);
 }
 
 /* Free the line_header structure *LH, and any arrays and strings it
@@ -5766,12 +6275,12 @@ dwarf_decode_line_header (unsigned int offset, bfd *abfd,
 
   if (dwarf2_per_objfile->line_buffer == NULL)
     {
-      complaint (&symfile_complaints, "missing .debug_line section");
+      complaint (&symfile_complaints, _("missing .debug_line 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.  */
+  /* 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 >= dwarf2_per_objfile->line_size)
     {
       dwarf2_statement_list_fits_in_line_number_section_complaint ();
@@ -5785,8 +6294,9 @@ dwarf_decode_line_header (unsigned int offset, bfd *abfd,
 
   line_ptr = dwarf2_per_objfile->line_buffer + offset;
 
-  /* read in the header */
-  lh->total_length = read_initial_length (abfd, line_ptr, NULL, &bytes_read);
+  /* Read in the header.  */
+  lh->total_length = 
+    read_initial_length (abfd, line_ptr, &cu->header, &bytes_read);
   line_ptr += bytes_read;
   if (line_ptr + lh->total_length > (dwarf2_per_objfile->line_buffer
                                     + dwarf2_per_objfile->line_size))
@@ -5819,7 +6329,7 @@ dwarf_decode_line_header (unsigned int offset, bfd *abfd,
       line_ptr += 1;
     }
 
-  /* Read directory table  */
+  /* Read directory table.  */
   while ((cur_dir = read_string (abfd, line_ptr, &bytes_read)) != NULL)
     {
       line_ptr += bytes_read;
@@ -5827,7 +6337,7 @@ dwarf_decode_line_header (unsigned int offset, bfd *abfd,
     }
   line_ptr += bytes_read;
 
-  /* Read file name table */
+  /* Read file name table */
   while ((cur_file = read_string (abfd, line_ptr, &bytes_read)) != NULL)
     {
       unsigned int dir_index, mod_time, length;
@@ -5848,7 +6358,7 @@ dwarf_decode_line_header (unsigned int offset, bfd *abfd,
   if (line_ptr > (dwarf2_per_objfile->line_buffer
                  + dwarf2_per_objfile->line_size))
     complaint (&symfile_complaints,
-              "line number info header doesn't fit in `.debug_line' section");
+              _("line number info header doesn't fit in `.debug_line' section"));
 
   discard_cleanups (back_to);
   return lh;
@@ -5894,7 +6404,7 @@ check_cu_functions (CORE_ADDR address, struct dwarf2_cu *cu)
     return address;
   if (address != fn->lowpc)
     complaint (&symfile_complaints,
-              "misplaced first line number at 0x%lx for '%s'",
+              _("misplaced first line number at 0x%lx for '%s'"),
               (unsigned long) address, fn->name);
   fn->seen_line = 1;
   return fn->lowpc;
@@ -5955,6 +6465,7 @@ dwarf_decode_lines (struct line_header *lh, char *comp_dir, bfd *abfd,
             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
@@ -5962,21 +6473,23 @@ dwarf_decode_lines (struct line_header *lh, char *comp_dir, bfd *abfd,
          dwarf2_start_subfile (fe->name, dir);
        }
 
-      /* Decode the table. */
+      /* 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.  */
+           {           
+             /* 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);
+              lh->file_names[file - 1].included_p = 1;
               if (!decode_for_pst_p)
                 {
-                 /* append row to matrix using current values */
+                 /* Append row to matrix using current values.  */
                  record_line (current_subfile, line, 
                               check_cu_functions (address, cu));
                 }
@@ -5985,13 +6498,15 @@ dwarf_decode_lines (struct line_header *lh, char *comp_dir, bfd *abfd,
          else switch (op_code)
            {
            case DW_LNS_extended_op:
-             line_ptr += 1;    /* ignore length */
+             read_unsigned_leb128 (abfd, line_ptr, &bytes_read);
+             line_ptr += bytes_read;
              extended_op = read_1_byte (abfd, line_ptr);
              line_ptr += 1;
              switch (extended_op)
                {
                case DW_LNE_end_sequence:
                  end_sequence = 1;
+                  lh->file_names[file - 1].included_p = 1;
                   if (!decode_for_pst_p)
                    record_line (current_subfile, 0, address);
                  break;
@@ -6021,11 +6536,12 @@ dwarf_decode_lines (struct line_header *lh, char *comp_dir, bfd *abfd,
                  break;
                default:
                  complaint (&symfile_complaints,
-                            "mangled .debug_line section");
+                            _("mangled .debug_line section"));
                  return;
                }
              break;
            case DW_LNS_copy:
+              lh->file_names[file - 1].included_p = 1;
               if (!decode_for_pst_p)
                record_line (current_subfile, line, 
                             check_cu_functions (address, cu));
@@ -6042,15 +6558,15 @@ dwarf_decode_lines (struct line_header *lh, char *comp_dir, bfd *abfd,
              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.  */
+                /* The arrays 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];
-                fe->included_p = 1;
                 if (fe->dir_index)
                   dir = lh->include_dirs[fe->dir_index - 1];
                 else
@@ -6071,9 +6587,9 @@ dwarf_decode_lines (struct line_header *lh, char *comp_dir, bfd *abfd,
              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.  */
+              255.  I.e., 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));
@@ -6083,8 +6599,10 @@ dwarf_decode_lines (struct line_header *lh, char *comp_dir, bfd *abfd,
              line_ptr += 2;
              break;
            default:
-             {  /* Unknown standard opcode, ignore it.  */
+             {
+               /* 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);
@@ -6104,9 +6622,29 @@ dwarf_decode_lines (struct line_header *lh, char *comp_dir, bfd *abfd,
       for (file_index = 0; file_index < lh->num_file_names; file_index++)
         if (lh->file_names[file_index].included_p == 1)
           {
-            char *include_name = lh->file_names [file_index].name;
-    
-            if (strcmp (include_name, pst->filename) != 0)
+            const struct file_entry fe = lh->file_names [file_index];
+            char *include_name = fe.name;
+            char *dir_name = NULL;
+            char *pst_filename = pst->filename;
+
+            if (fe.dir_index)
+              dir_name = lh->include_dirs[fe.dir_index - 1];
+
+            if (!IS_ABSOLUTE_PATH (include_name) && dir_name != NULL)
+              {
+                include_name =
+                  concat (dir_name, SLASH_STRING, include_name, NULL);
+                make_cleanup (xfree, include_name);
+              }
+
+            if (!IS_ABSOLUTE_PATH (pst_filename) && pst->dirname != NULL)
+              {
+                pst_filename =
+                  concat (pst->dirname, SLASH_STRING, pst_filename, NULL);
+                make_cleanup (xfree, pst_filename);
+              }
+
+            if (strcmp (include_name, pst_filename) != 0)
               dwarf2_create_include_psymtab (include_name, pst, objfile);
           }
     }
@@ -6364,7 +6902,8 @@ new_symbol (struct die_info *die, struct type *type, struct dwarf2_cu *cu)
             read_structure_type, and the correct name is saved in
             the type.  */
 
-         if (cu->language == language_cplus)
+         if (cu->language == language_cplus
+             || cu->language == language_java)
            {
              struct type *type = SYMBOL_TYPE (sym);
              
@@ -6381,7 +6920,7 @@ new_symbol (struct die_info *die, struct type *type, struct dwarf2_cu *cu)
            }
 
          {
-           /* NOTE: carlton/2003-11-10: C++ class symbols shouldn't
+           /* NOTE: carlton/2003-11-10: C++ and Java class symbols shouldn't
               really ever be static objects: otherwise, if you try
               to, say, break of a class's method and you're in a file
               which doesn't mention that class, it won't work unless
@@ -6392,15 +6931,18 @@ new_symbol (struct die_info *die, struct type *type, struct dwarf2_cu *cu)
            struct pending **list_to_add;
 
            list_to_add = (cu->list_in_scope == &file_symbols
-                          && cu->language == language_cplus
+                          && (cu->language == language_cplus
+                              || cu->language == language_java)
                           ? &global_symbols : cu->list_in_scope);
          
            add_symbol_to_list (sym, list_to_add);
 
            /* 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)
+              defines a typedef for "foo".  A Java class declaration also
+              defines a typedef for the class.  Synthesize a typedef symbol
+              so that "ptype foo" works as expected.  */
+           if (cu->language == language_cplus
+               || cu->language == language_java)
              {
                struct symbol *typedef_sym = (struct symbol *)
                  obstack_alloc (&objfile->objfile_obstack,
@@ -6411,7 +6953,7 @@ new_symbol (struct die_info *die, struct type *type, struct dwarf2_cu *cu)
                   this objfile, so we don't need to duplicate it for
                   the type.  */
                if (TYPE_NAME (SYMBOL_TYPE (sym)) == 0)
-                 TYPE_NAME (SYMBOL_TYPE (sym)) = SYMBOL_NATURAL_NAME (sym);
+                 TYPE_NAME (SYMBOL_TYPE (sym)) = SYMBOL_SEARCH_NAME (sym);
                add_symbol_to_list (typedef_sym, list_to_add);
              }
          }
@@ -6420,10 +6962,9 @@ new_symbol (struct die_info *die, struct type *type, struct dwarf2_cu *cu)
          if (processing_has_namespace_info
              && processing_current_prefix[0] != '\0')
            {
-             SYMBOL_LINKAGE_NAME (sym) = obconcat (&objfile->objfile_obstack,
-                                                   processing_current_prefix,
-                                                   "::",
-                                                   name);
+             SYMBOL_LINKAGE_NAME (sym) = typename_concat (&objfile->objfile_obstack,
+                                                          processing_current_prefix,
+                                                          name, cu);
            }
          SYMBOL_CLASS (sym) = LOC_TYPEDEF;
          SYMBOL_DOMAIN (sym) = VAR_DOMAIN;
@@ -6439,10 +6980,9 @@ new_symbol (struct die_info *die, struct type *type, struct dwarf2_cu *cu)
          if (processing_has_namespace_info
              && processing_current_prefix[0] != '\0')
            {
-             SYMBOL_LINKAGE_NAME (sym) = obconcat (&objfile->objfile_obstack,
-                                                   processing_current_prefix,
-                                                   "::",
-                                                   name);
+             SYMBOL_LINKAGE_NAME (sym) = typename_concat (&objfile->objfile_obstack,
+                                                          processing_current_prefix,
+                                                          name, cu);
            }
          attr = dwarf2_attr (die, DW_AT_const_value, cu);
          if (attr)
@@ -6456,7 +6996,8 @@ new_symbol (struct die_info *die, struct type *type, struct dwarf2_cu *cu)
            struct pending **list_to_add;
 
            list_to_add = (cu->list_in_scope == &file_symbols
-                          && cu->language == language_cplus
+                          && (cu->language == language_cplus
+                              || cu->language == language_java)
                           ? &global_symbols : cu->list_in_scope);
          
            add_symbol_to_list (sym, list_to_add);
@@ -6471,7 +7012,7 @@ new_symbol (struct die_info *die, struct type *type, struct dwarf2_cu *cu)
             trash data, but since we must specifically ignore things
             we don't recognize, there is nothing else we should do at
             this point. */
-         complaint (&symfile_complaints, "unsupported tag: '%s'",
+         complaint (&symfile_complaints, _("unsupported tag: '%s'"),
                     dwarf_tag_name (die->tag));
          break;
        }
@@ -6551,7 +7092,7 @@ dwarf2_const_value (struct attribute *attr, struct symbol *sym,
 
     default:
       complaint (&symfile_complaints,
-                "unsupported const value attribute form: '%s'",
+                _("unsupported const value attribute form: '%s'"),
                 dwarf_form_name (attr->form));
       SYMBOL_VALUE (sym) = 0;
       SYMBOL_CLASS (sym) = LOC_CONST;
@@ -6590,7 +7131,6 @@ die_type (struct die_info *die, struct dwarf2_cu *cu)
   struct type *type;
   struct attribute *type_attr;
   struct die_info *type_die;
-  unsigned int ref;
 
   type_attr = dwarf2_attr (die, DW_AT_type, cu);
   if (!type_attr)
@@ -6599,21 +7139,13 @@ die_type (struct die_info *die, struct dwarf2_cu *cu)
       return dwarf2_fundamental_type (cu->objfile, FT_VOID, cu);
     }
   else
-    {
-      ref = dwarf2_get_ref_die_offset (type_attr, cu);
-      type_die = follow_die_ref (ref);
-      if (!type_die)
-       {
-         error ("Dwarf Error: Cannot find referent at offset %d [in module %s]", 
-                         ref, cu->objfile->name);
-         return NULL;
-       }
-    }
+    type_die = follow_die_ref (die, type_attr, cu);
+
   type = tag_type_to_type (type_die, cu);
   if (!type)
     {
       dump_die (type_die);
-      error ("Dwarf Error: Problem turning type die at offset into gdb type [in module %s]",
+      error (_("Dwarf Error: Problem turning type die at offset into gdb type [in module %s]"),
                      cu->objfile->name);
     }
   return type;
@@ -6628,49 +7160,23 @@ die_containing_type (struct die_info *die, struct dwarf2_cu *cu)
   struct type *type = NULL;
   struct attribute *type_attr;
   struct die_info *type_die = NULL;
-  unsigned int ref;
 
   type_attr = dwarf2_attr (die, DW_AT_containing_type, cu);
   if (type_attr)
     {
-      ref = dwarf2_get_ref_die_offset (type_attr, cu);
-      type_die = follow_die_ref (ref);
-      if (!type_die)
-       {
-         error ("Dwarf Error: Cannot find referent at offset %d [in module %s]", ref, 
-                         cu->objfile->name);
-         return NULL;
-       }
+      type_die = follow_die_ref (die, type_attr, cu);
       type = tag_type_to_type (type_die, cu);
     }
   if (!type)
     {
       if (type_die)
        dump_die (type_die);
-      error ("Dwarf Error: Problem turning containing type into gdb type [in module %s]"
+      error (_("Dwarf Error: Problem turning containing type into gdb type [in module %s]")
                      cu->objfile->name);
     }
   return type;
 }
 
-#if 0
-static struct type *
-type_at_offset (unsigned int offset, struct dwarf2_cu *cu)
-{
-  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, cu);
-  return type;
-}
-#endif
-
 static struct type *
 tag_type_to_type (struct die_info *die, struct dwarf2_cu *cu)
 {
@@ -6684,7 +7190,7 @@ tag_type_to_type (struct die_info *die, struct dwarf2_cu *cu)
       if (!die->type)
        {
          dump_die (die);
-         error ("Dwarf Error: Cannot find type of die [in module %s]"
+         error (_("Dwarf Error: Cannot find type of die [in module %s]")
                          cu->objfile->name);
        }
       return die->type;
@@ -6744,7 +7250,7 @@ read_type_die (struct die_info *die, struct dwarf2_cu *cu)
       read_base_type (die, cu);
       break;
     default:
-      complaint (&symfile_complaints, "unexepected tag in read_type_die: '%s'",
+      complaint (&symfile_complaints, _("unexepected tag in read_type_die: '%s'"),
                 dwarf_tag_name (die->tag));
       break;
     }
@@ -6765,7 +7271,8 @@ determine_prefix (struct die_info *die, struct dwarf2_cu *cu)
 {
   struct die_info *parent;
 
-  if (cu->language != language_cplus)
+  if (cu->language != language_cplus
+      && cu->language != language_java)
     return NULL;
 
   parent = die->parent;
@@ -6789,9 +7296,10 @@ determine_prefix (struct die_info *die, struct dwarf2_cu *cu)
            {
              int dummy;
              char *parent_prefix = determine_prefix (parent, cu);
-             char *retval = typename_concat (parent_prefix,
+             char *retval = typename_concat (NULL, parent_prefix,
                                              namespace_name (parent, &dummy,
-                                                             cu));
+                                                             cu),
+                                             cu);
              xfree (parent_prefix);
              return retval;
            }
@@ -6824,25 +7332,47 @@ determine_prefix (struct die_info *die, struct dwarf2_cu *cu)
     }
 }
 
-/* Return a newly-allocated string formed by concatenating PREFIX,
-   "::", and SUFFIX, except that if PREFIX is NULL or the empty
-   string, just return a copy of SUFFIX.  */
+/* Return a newly-allocated string formed by concatenating PREFIX and
+   SUFFIX with appropriate separator.  If PREFIX or SUFFIX is NULL or empty, then
+   simply copy the SUFFIX or PREFIX, respectively.  If OBS is non-null,
+   perform an obconcat, otherwise allocate storage for the result.  The CU argument
+   is used to determine the language and hence, the appropriate separator.  */
+
+#define MAX_SEP_LEN 2  /* sizeof ("::")  */
 
 static char *
-typename_concat (const char *prefix, const char *suffix)
+typename_concat (struct obstack *obs, const char *prefix, const char *suffix, 
+                struct dwarf2_cu *cu)
 {
-  if (prefix == NULL || prefix[0] == '\0')
-    return xstrdup (suffix);
-  else
-    {
-      char *retval = xmalloc (strlen (prefix) + 2 + strlen (suffix) + 1);
+  char *sep;
 
-      strcpy (retval, prefix);
-      strcat (retval, "::");
-      strcat (retval, suffix);
+  if (suffix == NULL || suffix[0] == '\0' || prefix == NULL || prefix[0] == '\0')
+    sep = "";
+  else if (cu->language == language_java)
+    sep = ".";
+  else
+    sep = "::";
 
+  if (obs == NULL)
+    {
+      char *retval = xmalloc (strlen (prefix) + MAX_SEP_LEN + strlen (suffix) + 1);
+      retval[0] = '\0';
+      
+      if (prefix)
+       {
+         strcpy (retval, prefix);
+         strcat (retval, sep);
+       }
+      if (suffix)
+       strcat (retval, suffix);
+      
       return retval;
     }
+  else
+    {
+      /* We have an obstack.  */
+      return obconcat (obs, prefix, sep, suffix);
+    }
 }
 
 static struct type *
@@ -7000,21 +7530,12 @@ static struct die_info *
 dwarf2_extension (struct die_info *die, struct dwarf2_cu *cu)
 {
   struct attribute *attr;
-  struct die_info *extension_die;
-  unsigned int ref;
 
   attr = dwarf2_attr (die, DW_AT_extension, cu);
   if (attr == NULL)
     return NULL;
 
-  ref = dwarf2_get_ref_die_offset (attr, cu);
-  extension_die = follow_die_ref (ref);
-  if (!extension_die)
-    {
-      error ("Dwarf Error: Cannot find referent at offset %d.", ref);
-    }
-
-  return extension_die;
+  return follow_die_ref (die, attr, cu);
 }
 
 /* Convert a DIE tag into its string name.  */
@@ -7843,7 +8364,7 @@ dump_die (struct die_info *die)
        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);
+         deprecated_print_address_numeric (DW_ADDR (&die->attrs[i]), 1, gdb_stderr);
          break;
        case DW_FORM_block2:
        case DW_FORM_block4:
@@ -7851,13 +8372,16 @@ dump_die (struct die_info *die)
        case DW_FORM_block1:
          fprintf_unfiltered (gdb_stderr, "block: size %d", DW_BLOCK (&die->attrs[i])->size);
          break;
+       case DW_FORM_ref1:
+       case DW_FORM_ref2:
+       case DW_FORM_ref4:
+         fprintf_unfiltered (gdb_stderr, "constant ref: %ld (adjusted)",
+                             (long) (DW_ADDR (&die->attrs[i])));
+         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]));
@@ -7901,22 +8425,16 @@ dump_die_list (struct die_info *die)
 }
 
 static void
-store_in_ref_table (unsigned int offset, struct die_info *die)
+store_in_ref_table (unsigned int offset, struct die_info *die,
+                   struct dwarf2_cu *cu)
 {
   int h;
   struct die_info *old;
 
   h = (offset % REF_HASH_SIZE);
-  old = die_ref_table[h];
+  old = cu->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));
+  cu->die_ref_table[h] = die;
 }
 
 static unsigned int
@@ -7927,18 +8445,16 @@ dwarf2_get_ref_die_offset (struct attribute *attr, struct dwarf2_cu *cu)
   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);
+      result = DW_ADDR (attr);
       break;
     default:
       complaint (&symfile_complaints,
-                "unsupported die ref attribute form: '%s'",
+                _("unsupported die ref attribute form: '%s'"),
                 dwarf_form_name (attr->form));
     }
   return result;
@@ -7960,28 +8476,48 @@ dwarf2_get_attr_constant_value (struct attribute *attr, int default_value)
     return DW_UNSND (attr);
   else
     {
-      complaint (&symfile_complaints, "Attribute value is not a constant (%s)",
+      complaint (&symfile_complaints, _("Attribute value is not a constant (%s)"),
                  dwarf_form_name (attr->form));
       return default_value;
     }
 }
 
 static struct die_info *
-follow_die_ref (unsigned int offset)
+follow_die_ref (struct die_info *src_die, struct attribute *attr,
+               struct dwarf2_cu *cu)
 {
   struct die_info *die;
+  unsigned int offset;
   int h;
+  struct die_info temp_die;
+  struct dwarf2_cu *target_cu;
+
+  offset = dwarf2_get_ref_die_offset (attr, cu);
+
+  if (DW_ADDR (attr) < cu->header.offset
+      || DW_ADDR (attr) >= cu->header.offset + cu->header.length)
+    {
+      struct dwarf2_per_cu_data *per_cu;
+      per_cu = dwarf2_find_containing_comp_unit (DW_ADDR (attr),
+                                                cu->objfile);
+      target_cu = per_cu->cu;
+    }
+  else
+    target_cu = cu;
 
   h = (offset % REF_HASH_SIZE);
-  die = die_ref_table[h];
+  die = target_cu->die_ref_table[h];
   while (die)
     {
       if (die->offset == offset)
-       {
-         return die;
-       }
+       return die;
       die = die->next_ref;
     }
+
+  error (_("Dwarf Error: Cannot find DIE at 0x%lx referenced from DIE "
+        "at 0x%lx [in module %s]"),
+        (long) src_die->offset, (long) offset, cu->objfile->name);
+
   return NULL;
 }
 
@@ -7991,7 +8527,7 @@ 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 [in module %s]",
+      error (_("Dwarf Error: internal error - invalid fundamental type id %d [in module %s]"),
             typeid, objfile->name);
     }
 
@@ -8225,7 +8761,7 @@ decode_locdesc (struct dwarf_block *blk, struct dwarf2_cu *cu)
           break;
 
        default:
-         complaint (&symfile_complaints, "unsupported stack op: '%s'",
+         complaint (&symfile_complaints, _("unsupported stack op: '%s'"),
                     dwarf_stack_op_name (op));
          return (stack[stacki]);
        }
@@ -8354,7 +8890,7 @@ consume_improper_spaces (const char *p, const char *body)
   if (*p == ' ')
     {
       complaint (&symfile_complaints,
-                "macro definition contains spaces in formal argument list:\n`%s'",
+                _("macro definition contains spaces in formal argument list:\n`%s'"),
                 body);
 
       while (*p == ' ')
@@ -8516,7 +9052,7 @@ dwarf_decode_macros (struct line_header *lh, unsigned int offset,
 
   if (dwarf2_per_objfile->macinfo_buffer == NULL)
     {
-      complaint (&symfile_complaints, "missing .debug_macinfo section");
+      complaint (&symfile_complaints, _("missing .debug_macinfo section"));
       return;
     }
 
@@ -8559,7 +9095,7 @@ dwarf_decode_macros (struct line_header *lh, unsigned int offset,
 
             if (! current_file)
              complaint (&symfile_complaints,
-                        "debug info gives macro %s outside of any file: %s",
+                        _("debug info gives macro %s outside of any file: %s"),
                         macinfo_type ==
                         DW_MACINFO_define ? "definition" : macinfo_type ==
                         DW_MACINFO_undef ? "undefinition" :
@@ -8593,7 +9129,7 @@ dwarf_decode_macros (struct line_header *lh, unsigned int offset,
         case DW_MACINFO_end_file:
           if (! current_file)
            complaint (&symfile_complaints,
-                      "macro debug info has an unmatched `close_file' directive");
+                      _("macro debug info has an unmatched `close_file' directive"));
           else
             {
               current_file = current_file->included_by;
@@ -8618,7 +9154,7 @@ dwarf_decode_macros (struct line_header *lh, unsigned int offset,
                   next_type = read_1_byte (abfd, mac_ptr);
                   if (next_type != 0)
                    complaint (&symfile_complaints,
-                              "no terminating 0-type entry for macros in `.debug_macinfo' section");
+                              _("no terminating 0-type entry for macros in `.debug_macinfo' section"));
 
                   return;
                 }
@@ -8674,7 +9210,7 @@ dwarf2_symbol_mark_computed (struct attribute *attr, struct symbol *sym,
       baton->base_address = cu->header.base_address;
       if (cu->header.base_known == 0)
        complaint (&symfile_complaints,
-                  "Location list used without specifying the CU base address.");
+                  _("Location list used without specifying the CU base address."));
 
       SYMBOL_OPS (sym) = &dwarf2_loclist_funcs;
       SYMBOL_LOCATION_BATON (sym) = baton;
@@ -8710,9 +9246,85 @@ dwarf2_symbol_mark_computed (struct attribute *attr, struct symbol *sym,
     }
 }
 
+/* Locate the compilation unit from CU's objfile which contains the
+   DIE at OFFSET.  Raises an error on failure.  */
+
+static struct dwarf2_per_cu_data *
+dwarf2_find_containing_comp_unit (unsigned long offset,
+                                 struct objfile *objfile)
+{
+  struct dwarf2_per_cu_data *this_cu;
+  int low, high;
+
+  low = 0;
+  high = dwarf2_per_objfile->n_comp_units - 1;
+  while (high > low)
+    {
+      int mid = low + (high - low) / 2;
+      if (dwarf2_per_objfile->all_comp_units[mid]->offset >= offset)
+       high = mid;
+      else
+       low = mid + 1;
+    }
+  gdb_assert (low == high);
+  if (dwarf2_per_objfile->all_comp_units[low]->offset > offset)
+    {
+      if (low == 0)
+       error (_("Dwarf Error: could not find partial DIE containing "
+              "offset 0x%lx [in module %s]"),
+              (long) offset, bfd_get_filename (objfile->obfd));
+
+      gdb_assert (dwarf2_per_objfile->all_comp_units[low-1]->offset <= offset);
+      return dwarf2_per_objfile->all_comp_units[low-1];
+    }
+  else
+    {
+      this_cu = dwarf2_per_objfile->all_comp_units[low];
+      if (low == dwarf2_per_objfile->n_comp_units - 1
+         && offset >= this_cu->offset + this_cu->length)
+       error (_("invalid dwarf2 offset %ld"), offset);
+      gdb_assert (offset < this_cu->offset + this_cu->length);
+      return this_cu;
+    }
+}
+
+/* Locate the compilation unit from OBJFILE which is located at exactly
+   OFFSET.  Raises an error on failure.  */
+
+static struct dwarf2_per_cu_data *
+dwarf2_find_comp_unit (unsigned long offset, struct objfile *objfile)
+{
+  struct dwarf2_per_cu_data *this_cu;
+  this_cu = dwarf2_find_containing_comp_unit (offset, objfile);
+  if (this_cu->offset != offset)
+    error (_("no compilation unit with offset %ld."), offset);
+  return this_cu;
+}
+
+/* Release one cached compilation unit, CU.  We unlink it from the tree
+   of compilation units, but we don't remove it from the read_in_chain;
+   the caller is responsible for that.  */
+
+static void
+free_one_comp_unit (void *data)
+{
+  struct dwarf2_cu *cu = data;
+
+  if (cu->per_cu != NULL)
+    cu->per_cu->cu = NULL;
+  cu->per_cu = NULL;
+
+  obstack_free (&cu->comp_unit_obstack, NULL);
+  if (cu->dies)
+    free_die_list (cu->dies);
+
+  xfree (cu);
+}
+
 /* This cleanup function is passed the address of a dwarf2_cu on the stack
-   when we're finished with it.  We can't free the pointer itself, but
-   release any associated storage.
+   when we're finished with it.  We can't free the pointer itself, but be
+   sure to unlink it from the cache.  Also release any associated storage
+   and perform cache maintenance.
 
    Only used during partial symbol parsing.  */
 
@@ -8723,6 +9335,263 @@ free_stack_comp_unit (void *data)
 
   obstack_free (&cu->comp_unit_obstack, NULL);
   cu->partial_dies = NULL;
+
+  if (cu->per_cu != NULL)
+    {
+      /* This compilation unit is on the stack in our caller, so we
+        should not xfree it.  Just unlink it.  */
+      cu->per_cu->cu = NULL;
+      cu->per_cu = NULL;
+
+      /* If we had a per-cu pointer, then we may have other compilation
+        units loaded, so age them now.  */
+      age_cached_comp_units ();
+    }
+}
+
+/* Free all cached compilation units.  */
+
+static void
+free_cached_comp_units (void *data)
+{
+  struct dwarf2_per_cu_data *per_cu, **last_chain;
+
+  per_cu = dwarf2_per_objfile->read_in_chain;
+  last_chain = &dwarf2_per_objfile->read_in_chain;
+  while (per_cu != NULL)
+    {
+      struct dwarf2_per_cu_data *next_cu;
+
+      next_cu = per_cu->cu->read_in_chain;
+
+      free_one_comp_unit (per_cu->cu);
+      *last_chain = next_cu;
+
+      per_cu = next_cu;
+    }
+}
+
+/* Increase the age counter on each cached compilation unit, and free
+   any that are too old.  */
+
+static void
+age_cached_comp_units (void)
+{
+  struct dwarf2_per_cu_data *per_cu, **last_chain;
+
+  dwarf2_clear_marks (dwarf2_per_objfile->read_in_chain);
+  per_cu = dwarf2_per_objfile->read_in_chain;
+  while (per_cu != NULL)
+    {
+      per_cu->cu->last_used ++;
+      if (per_cu->cu->last_used <= dwarf2_max_cache_age)
+       dwarf2_mark (per_cu->cu);
+      per_cu = per_cu->cu->read_in_chain;
+    }
+
+  per_cu = dwarf2_per_objfile->read_in_chain;
+  last_chain = &dwarf2_per_objfile->read_in_chain;
+  while (per_cu != NULL)
+    {
+      struct dwarf2_per_cu_data *next_cu;
+
+      next_cu = per_cu->cu->read_in_chain;
+
+      if (!per_cu->cu->mark)
+       {
+         free_one_comp_unit (per_cu->cu);
+         *last_chain = next_cu;
+       }
+      else
+       last_chain = &per_cu->cu->read_in_chain;
+
+      per_cu = next_cu;
+    }
+}
+
+/* Remove a single compilation unit from the cache.  */
+
+static void
+free_one_cached_comp_unit (void *target_cu)
+{
+  struct dwarf2_per_cu_data *per_cu, **last_chain;
+
+  per_cu = dwarf2_per_objfile->read_in_chain;
+  last_chain = &dwarf2_per_objfile->read_in_chain;
+  while (per_cu != NULL)
+    {
+      struct dwarf2_per_cu_data *next_cu;
+
+      next_cu = per_cu->cu->read_in_chain;
+
+      if (per_cu->cu == target_cu)
+       {
+         free_one_comp_unit (per_cu->cu);
+         *last_chain = next_cu;
+         break;
+       }
+      else
+       last_chain = &per_cu->cu->read_in_chain;
+
+      per_cu = next_cu;
+    }
+}
+
+/* A pair of DIE offset and GDB type pointer.  We store these
+   in a hash table separate from the DIEs, and preserve them
+   when the DIEs are flushed out of cache.  */
+
+struct dwarf2_offset_and_type
+{
+  unsigned int offset;
+  struct type *type;
+};
+
+/* Hash function for a dwarf2_offset_and_type.  */
+
+static hashval_t
+offset_and_type_hash (const void *item)
+{
+  const struct dwarf2_offset_and_type *ofs = item;
+  return ofs->offset;
+}
+
+/* Equality function for a dwarf2_offset_and_type.  */
+
+static int
+offset_and_type_eq (const void *item_lhs, const void *item_rhs)
+{
+  const struct dwarf2_offset_and_type *ofs_lhs = item_lhs;
+  const struct dwarf2_offset_and_type *ofs_rhs = item_rhs;
+  return ofs_lhs->offset == ofs_rhs->offset;
+}
+
+/* Set the type associated with DIE to TYPE.  Save it in CU's hash
+   table if necessary.  */
+
+static void
+set_die_type (struct die_info *die, struct type *type, struct dwarf2_cu *cu)
+{
+  struct dwarf2_offset_and_type **slot, ofs;
+
+  die->type = type;
+
+  if (cu->per_cu == NULL)
+    return;
+
+  if (cu->per_cu->type_hash == NULL)
+    cu->per_cu->type_hash
+      = htab_create_alloc_ex (cu->header.length / 24,
+                             offset_and_type_hash,
+                             offset_and_type_eq,
+                             NULL,
+                             &cu->objfile->objfile_obstack,
+                             hashtab_obstack_allocate,
+                             dummy_obstack_deallocate);
+
+  ofs.offset = die->offset;
+  ofs.type = type;
+  slot = (struct dwarf2_offset_and_type **)
+    htab_find_slot_with_hash (cu->per_cu->type_hash, &ofs, ofs.offset, INSERT);
+  *slot = obstack_alloc (&cu->objfile->objfile_obstack, sizeof (**slot));
+  **slot = ofs;
+}
+
+/* Find the type for DIE in TYPE_HASH, or return NULL if DIE does not
+   have a saved type.  */
+
+static struct type *
+get_die_type (struct die_info *die, htab_t type_hash)
+{
+  struct dwarf2_offset_and_type *slot, ofs;
+
+  ofs.offset = die->offset;
+  slot = htab_find_with_hash (type_hash, &ofs, ofs.offset);
+  if (slot)
+    return slot->type;
+  else
+    return NULL;
+}
+
+/* Restore the types of the DIE tree starting at START_DIE from the hash
+   table saved in CU.  */
+
+static void
+reset_die_and_siblings_types (struct die_info *start_die, struct dwarf2_cu *cu)
+{
+  struct die_info *die;
+
+  if (cu->per_cu->type_hash == NULL)
+    return;
+
+  for (die = start_die; die != NULL; die = die->sibling)
+    {
+      die->type = get_die_type (die, cu->per_cu->type_hash);
+      if (die->child != NULL)
+       reset_die_and_siblings_types (die->child, cu);
+    }
+}
+
+/* Set the mark field in CU and in every other compilation unit in the
+   cache that we must keep because we are keeping CU.  */
+
+/* Add a dependence relationship from CU to REF_PER_CU.  */
+
+static void
+dwarf2_add_dependence (struct dwarf2_cu *cu,
+                      struct dwarf2_per_cu_data *ref_per_cu)
+{
+  void **slot;
+
+  if (cu->dependencies == NULL)
+    cu->dependencies
+      = htab_create_alloc_ex (5, htab_hash_pointer, htab_eq_pointer,
+                             NULL, &cu->comp_unit_obstack,
+                             hashtab_obstack_allocate,
+                             dummy_obstack_deallocate);
+
+  slot = htab_find_slot (cu->dependencies, ref_per_cu, INSERT);
+  if (*slot == NULL)
+    *slot = ref_per_cu;
+}
+
+/* Set the mark field in CU and in every other compilation unit in the
+   cache that we must keep because we are keeping CU.  */
+
+static int
+dwarf2_mark_helper (void **slot, void *data)
+{
+  struct dwarf2_per_cu_data *per_cu;
+
+  per_cu = (struct dwarf2_per_cu_data *) *slot;
+  if (per_cu->cu->mark)
+    return 1;
+  per_cu->cu->mark = 1;
+
+  if (per_cu->cu->dependencies != NULL)
+    htab_traverse (per_cu->cu->dependencies, dwarf2_mark_helper, NULL);
+
+  return 1;
+}
+
+static void
+dwarf2_mark (struct dwarf2_cu *cu)
+{
+  if (cu->mark)
+    return;
+  cu->mark = 1;
+  if (cu->dependencies != NULL)
+    htab_traverse (cu->dependencies, dwarf2_mark_helper, NULL);
+}
+
+static void
+dwarf2_clear_marks (struct dwarf2_per_cu_data *per_cu)
+{
+  while (per_cu)
+    {
+      per_cu->cu->mark = 0;
+      per_cu = per_cu->cu->read_in_chain;
+    }
 }
 
 /* Allocation function for the libiberty hash table which uses an
@@ -8768,10 +9637,49 @@ partial_die_eq (const void *item_lhs, const void *item_rhs)
   return part_die_lhs->offset == part_die_rhs->offset;
 }
 
+static struct cmd_list_element *set_dwarf2_cmdlist;
+static struct cmd_list_element *show_dwarf2_cmdlist;
+
+static void
+set_dwarf2_cmd (char *args, int from_tty)
+{
+  help_list (set_dwarf2_cmdlist, "maintenance set dwarf2 ", -1, gdb_stdout);
+}
+
+static void
+show_dwarf2_cmd (char *args, int from_tty)
+{ 
+  cmd_show_list (show_dwarf2_cmdlist, from_tty, "");
+}
+
 void _initialize_dwarf2_read (void);
 
 void
 _initialize_dwarf2_read (void)
 {
   dwarf2_objfile_data_key = register_objfile_data ();
+
+  add_prefix_cmd ("dwarf2", class_maintenance, set_dwarf2_cmd, _("\
+Set DWARF 2 specific variables.\n\
+Configure DWARF 2 variables such as the cache size"),
+                  &set_dwarf2_cmdlist, "maintenance set dwarf2 ",
+                  0/*allow-unknown*/, &maintenance_set_cmdlist);
+
+  add_prefix_cmd ("dwarf2", class_maintenance, show_dwarf2_cmd, _("\
+Show DWARF 2 specific variables\n\
+Show DWARF 2 variables such as the cache size"),
+                  &show_dwarf2_cmdlist, "maintenance show dwarf2 ",
+                  0/*allow-unknown*/, &maintenance_show_cmdlist);
+
+  add_setshow_zinteger_cmd ("max-cache-age", class_obscure,
+                           &dwarf2_max_cache_age, _("\
+Set the upper bound on the age of cached dwarf2 compilation units."), _("\
+Show the upper bound on the age of cached dwarf2 compilation units."), _("\
+A higher limit means that cached compilation units will be stored\n\
+in memory longer, and more total memory will be used.  Zero disables\n\
+caching, which can slow down startup."),
+                           NULL,
+                           show_dwarf2_max_cache_age,
+                           &set_dwarf2_cmdlist,
+                           &show_dwarf2_cmdlist);
 }
This page took 0.067825 seconds and 4 git commands to generate.