2006-02-21 Paul Brook <paul@codesourcery.com>
[deliverable/binutils-gdb.git] / gdb / dwarf2read.c
index 49a003f57866f620c593437deaa68562659d4be6..6fe9245f4a24c86dec7b5480def5b46e1459e215 100644 (file)
@@ -1,6 +1,7 @@
 /* DWARF 2 debugging format support for GDB.
-   Copyright 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003,
-   2004
+
+   Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003,
+   2004, 2005, 2006
    Free Software Foundation, Inc.
 
    Adapted by Gary Funck (gary@intrepid.com), Intrepid Technology,
@@ -24,8 +25,8 @@
 
    You should have received a copy of the GNU General Public License
    along with this program; if not, write to the Free Software
-   Foundation, Inc., 59 Temple Place - Suite 330,
-   Boston, MA 02111-1307, USA.  */
+   Foundation, Inc., 51 Franklin Street, Fifth Floor,
+   Boston, MA 02110-1301, USA.  */
 
 #include "defs.h"
 #include "bfd.h"
@@ -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"
@@ -159,13 +162,24 @@ struct dwarf2_per_objfile
   unsigned int eh_frame_size;
 
   /* Loaded data from the sections.  */
-  char *info_buffer;
-  char *abbrev_buffer;
-  char *line_buffer;
-  char *str_buffer;
-  char *macinfo_buffer;
-  char *ranges_buffer;
-  char *loc_buffer;
+  gdb_byte *info_buffer;
+  gdb_byte *abbrev_buffer;
+  gdb_byte *line_buffer;
+  gdb_byte *str_buffer;
+  gdb_byte *macinfo_buffer;
+  gdb_byte *ranges_buffer;
+  gdb_byte *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.  */
+  gdb_byte *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.  */
+  gdb_byte *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
@@ -299,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
@@ -306,6 +352,43 @@ 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**30-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 : 30;
+
+  /* Flag indicating this compilation unit will be read in before
+     any of the current compilation units are processed.  */
+  unsigned long queued : 1;
+
+  /* This flag will be set if we need to load absolutely all DIEs
+     for this compilation unit, instead of just the ones we think
+     are interesting.  It gets set if we look for a DIE in the
+     hash table and don't find it.  */
+  unsigned int load_all_dies : 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.  */
@@ -348,7 +431,7 @@ struct line_header
 
   /* The start and end of the statement program following this
      header.  These point into dwarf2_per_objfile->line_buffer.  */
-  char *statement_program_start, *statement_program_end;
+  gdb_byte *statement_program_start, *statement_program_end;
 };
 
 /* When we construct a partial symbol table entry we only
@@ -398,7 +481,7 @@ struct partial_die_info
 
     /* Pointer into the info_buffer pointing at the target of
        DW_AT_sibling, if any.  */
-    char *sibling;
+    gdb_byte *sibling;
 
     /* If HAS_SPECIFICATION, the offset of the DIE referred to by
        DW_AT_specification (or DW_AT_abstract_origin or
@@ -488,20 +571,13 @@ struct function_range
 struct dwarf_block
   {
     unsigned int size;
-    char *data;
+    gdb_byte *data;
   };
 
 #ifndef ATTR_ALLOC_CHUNK
 #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
@@ -510,28 +586,6 @@ static struct die_info *die_ref_table[REF_HASH_SIZE];
 /* A zeroed version of a partial die for initialization purposes.  */
 static struct partial_die_info zeroed_partial_die;
 
-/* FIXME: decode_locdesc sets these variables to describe the location
-   to the caller.  These ought to be a structure or something.   If
-   none of the flags are set, the object lives at the address returned
-   by decode_locdesc.  */
-
-static int 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.  */
@@ -585,19 +639,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
@@ -605,7 +686,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);
 }
 
@@ -613,14 +694,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);
 }
 
@@ -628,7 +709,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 */
@@ -664,80 +745,81 @@ static void add_partial_namespace (struct partial_die_info *pdi,
 static void add_partial_enumeration (struct partial_die_info *enum_pdi,
                                     struct dwarf2_cu *cu);
 
-static char *locate_pdi_sibling (struct partial_die_info *orig_pdi,
-                                char *info_ptr,
-                                bfd *abfd,
-                                struct dwarf2_cu *cu);
+static gdb_byte *locate_pdi_sibling (struct partial_die_info *orig_pdi,
+                                     gdb_byte *info_ptr,
+                                     bfd *abfd,
+                                     struct dwarf2_cu *cu);
 
 static void dwarf2_psymtab_to_symtab (struct partial_symtab *);
 
 static void psymtab_to_symtab_1 (struct partial_symtab *);
 
-char *dwarf2_read_section (struct objfile *, asection *);
+gdb_byte *dwarf2_read_section (struct objfile *, asection *);
 
 static void dwarf2_read_abbrevs (bfd *abfd, struct dwarf2_cu *cu);
 
 static void dwarf2_free_abbrev_table (void *);
 
-static struct abbrev_info *peek_die_abbrev (char *, int *, struct dwarf2_cu *);
+static struct abbrev_info *peek_die_abbrev (gdb_byte *, unsigned int *,
+                                           struct dwarf2_cu *);
 
 static struct abbrev_info *dwarf2_lookup_abbrev (unsigned int,
                                                 struct dwarf2_cu *);
 
-static struct partial_die_info *load_partial_dies (bfd *, char *, int,
+static struct partial_die_info *load_partial_dies (bfd *, gdb_byte *, int,
                                                   struct dwarf2_cu *);
 
-static char *read_partial_die (struct partial_die_info *,
-                              struct abbrev_info *abbrev, unsigned int,
-                              bfd *, char *, struct dwarf2_cu *);
+static gdb_byte *read_partial_die (struct partial_die_info *,
+                                   struct abbrev_info *abbrev, unsigned int,
+                                   bfd *, gdb_byte *, 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 *);
 
-static char *read_full_die (struct die_info **, bfd *, char *,
-                           struct dwarf2_cu *, int *);
+static gdb_byte *read_full_die (struct die_info **, bfd *, gdb_byte *,
+                                struct dwarf2_cu *, int *);
 
-static char *read_attribute (struct attribute *, struct attr_abbrev *,
-                            bfd *, char *, struct dwarf2_cu *);
+static gdb_byte *read_attribute (struct attribute *, struct attr_abbrev *,
+                                 bfd *, gdb_byte *, struct dwarf2_cu *);
 
-static char *read_attribute_value (struct attribute *, unsigned,
-                            bfd *, char *, struct dwarf2_cu *);
+static gdb_byte *read_attribute_value (struct attribute *, unsigned,
+                                       bfd *, gdb_byte *, struct dwarf2_cu *);
 
-static unsigned int read_1_byte (bfd *, char *);
+static unsigned int read_1_byte (bfd *, gdb_byte *);
 
-static int read_1_signed_byte (bfd *, char *);
+static int read_1_signed_byte (bfd *, gdb_byte *);
 
-static unsigned int read_2_bytes (bfd *, char *);
+static unsigned int read_2_bytes (bfd *, gdb_byte *);
 
-static unsigned int read_4_bytes (bfd *, char *);
+static unsigned int read_4_bytes (bfd *, gdb_byte *);
 
-static unsigned long read_8_bytes (bfd *, char *);
+static unsigned long read_8_bytes (bfd *, gdb_byte *);
 
-static CORE_ADDR read_address (bfd *, char *ptr, struct dwarf2_cu *,
-                              int *bytes_read);
+static CORE_ADDR read_address (bfd *, gdb_byte *ptr, struct dwarf2_cu *,
+                              unsigned int *);
 
-static LONGEST read_initial_length (bfd *, char *,
-                                    struct comp_unit_head *, int *bytes_read);
+static LONGEST read_initial_length (bfd *, gdb_byte *,
+                                    struct comp_unit_head *, unsigned int *);
 
-static LONGEST read_offset (bfd *, char *, const struct comp_unit_head *,
-                            int *bytes_read);
+static LONGEST read_offset (bfd *, gdb_byte *, const struct comp_unit_head *,
+                            unsigned int *);
 
-static char *read_n_bytes (bfd *, char *, unsigned int);
+static gdb_byte *read_n_bytes (bfd *, gdb_byte *, unsigned int);
 
-static char *read_string (bfd *, char *, unsigned int *);
+static char *read_string (bfd *, gdb_byte *, unsigned int *);
 
-static char *read_indirect_string (bfd *, char *, const struct comp_unit_head *,
-                                  unsigned int *);
+static char *read_indirect_string (bfd *, gdb_byte *,
+                                   const struct comp_unit_head *,
+                                   unsigned int *);
 
-static unsigned long read_unsigned_leb128 (bfd *, char *, unsigned int *);
+static unsigned long read_unsigned_leb128 (bfd *, gdb_byte *, unsigned int *);
 
-static long read_signed_leb128 (bfd *, char *, unsigned int *);
+static long read_signed_leb128 (bfd *, gdb_byte *, unsigned int *);
 
-static char *skip_leb128 (bfd *, char *);
+static gdb_byte *skip_leb128 (bfd *, gdb_byte *);
 
 static void set_cu_language (unsigned int, struct dwarf2_cu *);
 
@@ -781,17 +863,16 @@ 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 *);
 
@@ -866,22 +947,20 @@ static void read_tag_string_type (struct die_info *, struct dwarf2_cu *);
 
 static void read_subroutine_type (struct die_info *, struct dwarf2_cu *);
 
-static struct die_info *read_comp_unit (char *, bfd *, struct dwarf2_cu *);
+static struct die_info *read_comp_unit (gdb_byte *, bfd *, struct dwarf2_cu *);
 
-static struct die_info *read_die_and_children (char *info_ptr, bfd *abfd,
+static struct die_info *read_die_and_children (gdb_byte *info_ptr, bfd *abfd,
                                               struct dwarf2_cu *,
-                                              char **new_info_ptr,
+                                              gdb_byte **new_info_ptr,
                                               struct die_info *parent);
 
-static struct die_info *read_die_and_siblings (char *info_ptr, bfd *abfd,
+static struct die_info *read_die_and_siblings (gdb_byte *info_ptr, bfd *abfd,
                                               struct dwarf2_cu *,
-                                              char **new_info_ptr,
+                                              gdb_byte **new_info_ptr,
                                               struct die_info *parent);
 
 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 *);
@@ -915,16 +994,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 *);
@@ -951,19 +1031,48 @@ static void
 dwarf2_symbol_mark_computed (struct attribute *attr, struct symbol *sym,
                             struct dwarf2_cu *cu);
 
-static char *skip_one_die (char *info_ptr, struct abbrev_info *abbrev,
-                          struct dwarf2_cu *cu);
+static gdb_byte *skip_one_die (gdb_byte *info_ptr, struct abbrev_info *abbrev,
+                               struct dwarf2_cu *cu);
 
 static void free_stack_comp_unit (void *);
 
-static void *hashtab_obstack_allocate (void *data, size_t size, size_t count);
-
-static void dummy_obstack_deallocate (void *object, void *data);
-
 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.  */
 
@@ -1138,10 +1247,10 @@ dwarf2_build_psymtabs_easy (struct objfile *objfile, int mainline)
   while ((pubnames_ptr - pubnames_buffer) < dwarf2_per_objfile->pubnames_size)
     {
       struct comp_unit_head cu_header;
-      int bytes_read;
+      unsigned int bytes_read;
 
       entry_length = read_initial_length (abfd, pubnames_ptr, &cu_header,
-                                         &bytes_read);
+                                          &bytes_read);
       pubnames_ptr += bytes_read;
       version = read_1_byte (abfd, pubnames_ptr);
       pubnames_ptr += 1;
@@ -1158,14 +1267,14 @@ 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 *
+static gdb_byte *
 read_comp_unit_head (struct comp_unit_head *cu_header,
-                    char *info_ptr, bfd *abfd)
+                    gdb_byte *info_ptr, bfd *abfd)
 {
   int signed_addr;
-  int bytes_read;
+  unsigned int bytes_read;
   cu_header->length = read_initial_length (abfd, info_ptr, cu_header,
                                            &bytes_read);
   info_ptr += bytes_read;
@@ -1179,35 +1288,35 @@ 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;
 }
 
-static char *
-partial_read_comp_unit_head (struct comp_unit_head *header, char *info_ptr,
+static gdb_byte *
+partial_read_comp_unit_head (struct comp_unit_head *header, gdb_byte *info_ptr,
                             bfd *abfd)
 {
-  char *beg_of_comp_unit = info_ptr;
+  gdb_byte *beg_of_comp_unit = 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));
@@ -1244,9 +1353,7 @@ 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 private part, then we'll have to add a
-     dedicated field for that in the dwarf2_pinfo structure.  */
+     the regular ones.  */
   subpst->read_symtab_private = NULL;
 }
 
@@ -1286,14 +1393,21 @@ dwarf2_build_psymtabs_hard (struct objfile *objfile, int mainline)
   /* Instead of reading this into a big buffer, we should probably use
      mmap()  on architectures that support it. (FIXME) */
   bfd *abfd = objfile->obfd;
-  char *info_ptr;
-  char *beg_of_comp_unit;
+  gdb_byte *info_ptr;
+  gdb_byte *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
@@ -1334,12 +1448,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,
@@ -1355,17 +1469,35 @@ dwarf2_build_psymtabs_hard (struct objfile *objfile, int mainline)
                                  objfile->global_psymbols.next,
                                  objfile->static_psymbols.next);
 
-         if (comp_unit_die.dirname)
-        pst->dirname = xstrdup (comp_unit_die.dirname);
+      if (comp_unit_die.dirname)
+       pst->dirname = xstrdup (comp_unit_die.dirname);
+
+      pst->read_symtab_private = (char *) this_cu;
 
-      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;
       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. */
@@ -1407,6 +1539,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,
@@ -1414,11 +1549,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;
+  gdb_byte *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;
+  gdb_byte *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;
+      gdb_byte *beg_of_comp_unit;
+      struct dwarf2_per_cu_data *this_cu;
+      unsigned long offset;
+      unsigned 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.
@@ -1511,7 +1760,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.
@@ -1537,15 +1787,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)
@@ -1556,7 +1804,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
@@ -1566,8 +1814,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.  */
@@ -1578,7 +1826,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;
     }
@@ -1599,7 +1847,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
@@ -1717,14 +1965,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,
@@ -1734,7 +1984,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);
@@ -1814,7 +2065,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)
     {
@@ -1826,16 +2078,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;
@@ -1880,7 +2130,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;
@@ -1893,7 +2143,8 @@ add_partial_enumeration (struct partial_die_info *enum_pdi,
    the initial number.  */
 
 static struct abbrev_info *
-peek_die_abbrev (char *info_ptr, int *bytes_read, struct dwarf2_cu *cu)
+peek_die_abbrev (gdb_byte *info_ptr, unsigned int *bytes_read,
+                struct dwarf2_cu *cu)
 {
   bfd *abfd = cu->objfile->obfd;
   unsigned int abbrev_number;
@@ -1907,7 +2158,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));
     }
 
@@ -1918,8 +2169,8 @@ peek_die_abbrev (char *info_ptr, int *bytes_read, struct dwarf2_cu *cu)
    pointer to the end of a series of DIEs, terminated by an empty
    DIE.  Any children of the skipped DIEs will also be skipped.  */
 
-static char *
-skip_children (char *info_ptr, struct dwarf2_cu *cu)
+static gdb_byte *
+skip_children (gdb_byte *info_ptr, struct dwarf2_cu *cu)
 {
   struct abbrev_info *abbrev;
   unsigned int bytes_read;
@@ -1940,8 +2191,8 @@ skip_children (char *info_ptr, struct dwarf2_cu *cu)
    ABBREV.  Returns a pointer to this DIE's sibling, skipping any
    children.  */
 
-static char *
-skip_one_die (char *info_ptr, struct abbrev_info *abbrev,
+static gdb_byte *
+skip_one_die (gdb_byte *info_ptr, struct abbrev_info *abbrev,
              struct dwarf2_cu *cu)
 {
   unsigned int bytes_read;
@@ -1957,7 +2208,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);
@@ -2022,7 +2273,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));
        }
@@ -2037,8 +2288,8 @@ skip_one_die (char *info_ptr, struct abbrev_info *abbrev,
 /* Locate ORIG_PDI's sibling; INFO_PTR should point to the start of
    the next DIE after ORIG_PDI.  */
 
-static char *
-locate_pdi_sibling (struct partial_die_info *orig_pdi, char *info_ptr,
+static gdb_byte *
+locate_pdi_sibling (struct partial_die_info *orig_pdi, gdb_byte *info_ptr,
                    bfd *abfd, struct dwarf2_cu *cu)
 {
   /* Do we know the sibling already?  */
@@ -2066,40 +2317,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++)
@@ -2108,6 +2446,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);
@@ -2119,7 +2458,9 @@ psymtab_to_symtab_1 (struct partial_symtab *pst)
         psymtab_to_symtab_1 (pst->dependencies[i]);
       }
 
-  if (pst->read_symtab_private == 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.  */
@@ -2127,39 +2468,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;
+  gdb_byte *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);
 
-  cu.header.offset = offset;
+  /* We've successfully allocated this compilation unit.  Let our caller
+     clean it up when finished with it.  */
+  discard_cleanups (free_cu_cleanup);
 
-  cu.list_in_scope = &file_symbols;
+  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;
+
+  baseaddr = ANOFFSET (objfile->section_offsets, SECT_OFF_TEXT (objfile));
+
+  /* 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.
@@ -2167,32 +2576,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));
 
@@ -2200,9 +2609,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;
@@ -2474,7 +2883,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);
 
@@ -2652,8 +3062,8 @@ dwarf2_get_pc_bounds (struct die_info *die, CORE_ADDR *lowpc,
          /* Base address selection entry.  */
          CORE_ADDR base;
          int found_base;
-         int dummy;
-         char *buffer;
+         unsigned int dummy;
+         gdb_byte *buffer;
          CORE_ADDR marker;
          int low_set;
  
@@ -2663,7 +3073,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 +3125,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;
                }
 
@@ -3040,11 +3450,11 @@ dwarf2_attach_fields_to_type (struct field_info *fip, struct type *type,
   if (fip->nbaseclasses)
     {
       int num_bytes = B_BYTES (fip->nbaseclasses);
-      char *pointer;
+      unsigned char *pointer;
 
       ALLOCATE_CPLUS_STRUCT_TYPE (type);
-      pointer = (char *) TYPE_ALLOC (type, num_bytes);
-      TYPE_FIELD_VIRTUAL_BITS (type) = (B_TYPE *) pointer;
+      pointer = TYPE_ALLOC (type, num_bytes);
+      TYPE_FIELD_VIRTUAL_BITS (type) = pointer;
       B_CLRALL (TYPE_FIELD_VIRTUAL_BITS (type), fip->nbaseclasses);
       TYPE_N_BASECLASSES (type) = fip->nbaseclasses;
     }
@@ -3071,7 +3481,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 +3590,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.  */
@@ -3272,10 +3682,13 @@ static int
 is_vtable_name (const char *name, struct dwarf2_cu *cu)
 {
   static const char vptr[] = "_vptr";
+  static const char vtable[] = "vtable";
 
-  /* C++ and some implementations of Java use this name.  */
-  if (strncmp (name, vptr, sizeof (vptr) - 1) == 0
-      && is_cplus_marker (name[sizeof (vptr) - 1]))
+  /* 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;
@@ -3316,7 +3729,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,
@@ -3364,7 +3778,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))
     {
@@ -3439,7 +3853,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) :
                               "");
                }
@@ -3448,6 +3862,28 @@ read_structure_type (struct die_info *die, struct dwarf2_cu *cu)
                  TYPE_VPTR_FIELDNO (type) = TYPE_VPTR_FIELDNO (t);
                }
            }
+         else if (cu->producer
+                  && strncmp (cu->producer,
+                              "IBM(R) XL C/C++ Advanced Edition", 32) == 0)
+           {
+             /* The IBM XLC compiler does not provide direct indication
+                of the containing type, but the vtable pointer is
+                always named __vfp.  */
+
+             int i;
+
+             for (i = TYPE_NFIELDS (type) - 1;
+                  i >= TYPE_N_BASECLASSES (type);
+                  --i)
+               {
+                 if (strcmp (TYPE_FIELD_NAME (type, i), "__vfp") == 0)
+                   {
+                     TYPE_VPTR_FIELDNO (type) = i;
+                     TYPE_VPTR_BASETYPE (type) = type;
+                     break;
+                   }
+               }
+           }
        }
 
       do_cleanups (back_to);
@@ -3518,11 +3954,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
        {
@@ -3542,11 +3976,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 *
@@ -3593,8 +4027,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)
@@ -3707,7 +4142,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;
     }
 
@@ -3767,7 +4203,7 @@ 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
@@ -3861,6 +4297,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);
 
@@ -3872,14 +4309,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;
     }
 
@@ -3899,7 +4330,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,
@@ -3919,6 +4350,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
@@ -3997,7 +4429,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?  */
@@ -4005,7 +4437,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
@@ -4029,7 +4461,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
@@ -4057,7 +4489,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
@@ -4071,7 +4503,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
@@ -4085,7 +4518,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
@@ -4137,7 +4571,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:
@@ -4164,12 +4598,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)
@@ -4194,7 +4629,7 @@ read_subroutine_type (struct die_info *die, struct dwarf2_cu *cu)
       /* Allocate storage for parameters and fill them in.  */
       TYPE_NFIELDS (ftype) = nparams;
       TYPE_FIELDS (ftype) = (struct field *)
-       TYPE_ALLOC (ftype, nparams * sizeof (struct field));
+       TYPE_ZALLOC (ftype, nparams * sizeof (struct field));
 
       child_die = die->child;
       while (child_die && child_die->tag)
@@ -4218,7 +4653,7 @@ read_subroutine_type (struct die_info *die, struct dwarf2_cu *cu)
        }
     }
 
-  die->type = ftype;
+  set_die_type (die, ftype, cu);
 }
 
 static void
@@ -4235,7 +4670,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);
     }
 }
@@ -4298,7 +4735,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;
        }
@@ -4323,7 +4760,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.  */
@@ -4345,7 +4782,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;
     }
 
@@ -4358,6 +4795,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);
@@ -4394,19 +4834,15 @@ 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);
 }
   
 
 /* Read a whole compilation unit into a linked list of dies.  */
 
 static struct die_info *
-read_comp_unit (char *info_ptr, bfd *abfd, struct dwarf2_cu *cu)
+read_comp_unit (gdb_byte *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);
 }
 
@@ -4417,17 +4853,17 @@ read_comp_unit (char *info_ptr, bfd *abfd, struct dwarf2_cu *cu)
    is the parent of the die in question.  */
 
 static struct die_info *
-read_die_and_children (char *info_ptr, bfd *abfd,
+read_die_and_children (gdb_byte *info_ptr, bfd *abfd,
                       struct dwarf2_cu *cu,
-                      char **new_info_ptr,
+                      gdb_byte **new_info_ptr,
                       struct die_info *parent)
 {
   struct die_info *die;
-  char *cur_ptr;
+  gdb_byte *cur_ptr;
   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)
     {
@@ -4450,13 +4886,13 @@ read_die_and_children (char *info_ptr, bfd *abfd,
    in read_die_and_children.  */
 
 static struct die_info *
-read_die_and_siblings (char *info_ptr, bfd *abfd,
+read_die_and_siblings (gdb_byte *info_ptr, bfd *abfd,
                       struct dwarf2_cu *cu,
-                      char **new_info_ptr,
+                      gdb_byte **new_info_ptr,
                       struct die_info *parent)
 {
   struct die_info *first_die, *last_sibling;
-  char *cur_ptr;
+  gdb_byte *cur_ptr;
 
   cur_ptr = info_ptr;
   first_die = last_sibling = NULL;
@@ -4506,41 +4942,27 @@ 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.  */
 
-char *
+gdb_byte *
 dwarf2_read_section (struct objfile *objfile, asection *sectp)
 {
   bfd *abfd = objfile->obfd;
-  char *buf, *retbuf;
+  gdb_byte *buf, *retbuf;
   bfd_size_type size = bfd_get_section_size (sectp);
 
   if (size == 0)
     return NULL;
 
-  buf = (char *) obstack_alloc (&objfile->objfile_obstack, size);
-  retbuf
-    = (char *) symfile_relocate_debug_section (abfd, sectp, (bfd_byte *) buf);
+  buf = obstack_alloc (&objfile->objfile_obstack, size);
+  retbuf = symfile_relocate_debug_section (abfd, sectp, buf);
   if (retbuf != NULL)
     return retbuf;
 
   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;
@@ -4556,7 +4978,7 @@ static void
 dwarf2_read_abbrevs (bfd *abfd, struct dwarf2_cu *cu)
 {
   struct comp_unit_head *cu_header = &cu->header;
-  char *abbrev_ptr;
+  gdb_byte *abbrev_ptr;
   struct abbrev_info *cur_abbrev;
   unsigned int abbrev_number, bytes_read, abbrev_name;
   unsigned int abbrev_form, hash_number;
@@ -4607,6 +5029,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);
@@ -4710,19 +5143,23 @@ is_type_tag_for_partial (int tag)
 /* Load all DIEs that are interesting for partial symbols into memory.  */
 
 static struct partial_die_info *
-load_partial_dies (bfd *abfd, char *info_ptr, int building_psymtab,
+load_partial_dies (bfd *abfd, gdb_byte *info_ptr, int building_psymtab,
                   struct dwarf2_cu *cu)
 {
   struct partial_die_info *part_die;
   struct partial_die_info *parent_die, *last_die, *first_die = NULL;
   struct abbrev_info *abbrev;
   unsigned int bytes_read;
+  unsigned int load_all = 0;
 
   int nesting_level = 1;
 
   parent_die = NULL;
   last_die = NULL;
 
+  if (cu->per_cu && cu->per_cu->load_all_dies)
+    load_all = 1;
+
   cu->partial_dies
     = htab_create_alloc_ex (cu->header.length / 12,
                            partial_die_hash,
@@ -4758,12 +5195,17 @@ load_partial_dies (bfd *abfd, char *info_ptr, int building_psymtab,
          continue;
        }
 
-      /* Check whether this DIE is interesting enough to save.  */
-      if (!is_type_tag_for_partial (abbrev->tag)
+      /* Check whether this DIE is interesting enough to save.  Normally
+        we would not be interested in members here, but there may be
+        later variables referencing them via DW_AT_specification (for
+        static members).  */
+      if (!load_all
+         && !is_type_tag_for_partial (abbrev->tag)
          && abbrev->tag != DW_TAG_enumerator
          && abbrev->tag != DW_TAG_subprogram
          && abbrev->tag != DW_TAG_variable
-         && abbrev->tag != DW_TAG_namespace)
+         && abbrev->tag != DW_TAG_namespace
+         && abbrev->tag != DW_TAG_member)
        {
          /* Otherwise we skip to the next sibling, if any.  */
          info_ptr = skip_one_die (info_ptr + bytes_read, abbrev, cu);
@@ -4816,11 +5258,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);
@@ -4862,9 +5305,11 @@ load_partial_dies (bfd *abfd, char *info_ptr, int building_psymtab,
 
         Adding more things than necessary to the hash table is harmless
         except for the performance cost.  Adding too few will result in
-        internal errors in find_partial_die.  */
+        wasted time in find_partial_die, when we reread the compilation
+        unit with load_all_dies set.  */
 
-      if (abbrev->tag == DW_TAG_subprogram
+      if (load_all
+         || abbrev->tag == DW_TAG_subprogram
          || abbrev->tag == DW_TAG_variable
          || abbrev->tag == DW_TAG_namespace
          || part_die->is_declaration)
@@ -4884,7 +5329,8 @@ load_partial_dies (bfd *abfd, char *info_ptr, int building_psymtab,
         languages we have to, both so that we can get at method physnames
         to infer fully qualified class names, and for DW_AT_specification.  */
       if (last_die->has_children
-         && (last_die->tag == DW_TAG_namespace
+         && (load_all
+             || last_die->tag == DW_TAG_namespace
              || last_die->tag == DW_TAG_enumeration_type
              || (cu->language != language_c
                  && (last_die->tag == DW_TAG_class_type
@@ -4905,11 +5351,11 @@ load_partial_dies (bfd *abfd, char *info_ptr, int building_psymtab,
 
 /* Read a minimal amount of information into the minimal die structure.  */
 
-static char *
+static gdb_byte *
 read_partial_die (struct partial_die_info *part_die,
                  struct abbrev_info *abbrev,
                  unsigned int abbrev_len, bfd *abfd,
-                 char *info_ptr, struct dwarf2_cu *cu)
+                 gdb_byte *info_ptr, struct dwarf2_cu *cu)
 {
   unsigned int bytes_read, i;
   struct attribute attr;
@@ -4995,7 +5441,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);
@@ -5036,30 +5482,71 @@ find_partial_die_in_comp_unit (unsigned long offset, struct dwarf2_cu *cu)
   part_die.offset = offset;
   lookup_die = htab_find_with_hash (cu->partial_dies, &part_die, offset);
 
-  if (lookup_die == NULL)
-    internal_error (__FILE__, __LINE__,
-                   "could not find partial DIE in cache\n");
-
   return lookup_die;
 }
 
 /* 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;
+  struct dwarf2_per_cu_data *per_cu = NULL;
+  struct partial_die_info *pd = NULL;
 
   if (offset >= cu->header.offset
       && offset < cu->header.offset + cu->header.length)
     {
-      *target_cu = cu;
-      return find_partial_die_in_comp_unit (offset, cu);
+      pd = find_partial_die_in_comp_unit (offset, cu);
+      if (pd != NULL)
+       return pd;
+    }
+
+  per_cu = dwarf2_find_containing_comp_unit (offset, cu->objfile);
+
+  if (per_cu->cu == NULL)
+    {
+      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;
+  pd = find_partial_die_in_comp_unit (offset, per_cu->cu);
+
+  if (pd == NULL && per_cu->load_all_dies == 0)
+    {
+      struct cleanup *back_to;
+      struct partial_die_info comp_unit_die;
+      struct abbrev_info *abbrev;
+      unsigned int bytes_read;
+      char *info_ptr;
+
+      per_cu->load_all_dies = 1;
+
+      /* Re-read the DIEs.  */
+      back_to = make_cleanup (null_cleanup, 0);
+      if (per_cu->cu->dwarf2_abbrevs == NULL)
+       {
+         dwarf2_read_abbrevs (per_cu->cu->objfile->obfd, per_cu->cu);
+         back_to = make_cleanup (dwarf2_free_abbrev_table, per_cu->cu);
+       }
+      info_ptr = per_cu->cu->header.first_die_ptr;
+      abbrev = peek_die_abbrev (info_ptr, &bytes_read, per_cu->cu);
+      info_ptr = read_partial_die (&comp_unit_die, abbrev, bytes_read,
+                                  per_cu->cu->objfile->obfd, info_ptr,
+                                  per_cu->cu);
+      if (comp_unit_die.has_children)
+       load_partial_dies (per_cu->cu->objfile->obfd, info_ptr, 0, per_cu->cu);
+      do_cleanups (back_to);
+
+      pd = find_partial_die_in_comp_unit (offset, per_cu->cu);
+    }
+
+  if (pd == NULL)
+    internal_error (__FILE__, __LINE__,
+                   _("could not find partial DIE 0x%lx in cache [from module %s]\n"),
+                   offset, bfd_get_filename (cu->objfile->obfd));
+  return pd;
 }
 
 /* Adjust PART_DIE before generating a symbol for it.  This function
@@ -5075,11 +5562,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)
        {
@@ -5110,8 +5596,8 @@ fixup_partial_die (struct partial_die_info *part_die,
    child, sibling, and parent fields.  Set HAS_CHILDREN to tell
    whether the die has children or not.  */
 
-static char *
-read_full_die (struct die_info **diep, bfd *abfd, char *info_ptr,
+static gdb_byte *
+read_full_die (struct die_info **diep, bfd *abfd, gdb_byte *info_ptr,
               struct dwarf2_cu *cu, int *has_children)
 {
   unsigned int abbrev_number, bytes_read, i, offset;
@@ -5135,7 +5621,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));
     }
@@ -5153,6 +5639,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;
@@ -5162,9 +5680,9 @@ read_full_die (struct die_info **diep, bfd *abfd, char *info_ptr,
 
 /* Read an attribute value described by an attribute form.  */
 
-static char *
+static gdb_byte *
 read_attribute_value (struct attribute *attr, unsigned form,
-                     bfd *abfd, char *info_ptr,
+                     bfd *abfd, gdb_byte *info_ptr,
                      struct dwarf2_cu *cu)
 {
   struct comp_unit_head *cu_header = &cu->header;
@@ -5249,23 +5767,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:
@@ -5274,7 +5793,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));
     }
@@ -5283,9 +5802,9 @@ read_attribute_value (struct attribute *attr, unsigned form,
 
 /* Read an attribute described by an abbreviated attribute.  */
 
-static char *
+static gdb_byte *
 read_attribute (struct attribute *attr, struct attr_abbrev *abbrev,
-               bfd *abfd, char *info_ptr, struct dwarf2_cu *cu)
+               bfd *abfd, gdb_byte *info_ptr, struct dwarf2_cu *cu)
 {
   attr->name = abbrev->name;
   return read_attribute_value (attr, abbrev->form, abfd, info_ptr, cu);
@@ -5294,49 +5813,50 @@ read_attribute (struct attribute *attr, struct attr_abbrev *abbrev,
 /* read dwarf information from a buffer */
 
 static unsigned int
-read_1_byte (bfd *abfd, char *buf)
+read_1_byte (bfd *abfd, gdb_byte *buf)
 {
-  return bfd_get_8 (abfd, (bfd_byte *) buf);
+  return bfd_get_8 (abfd, buf);
 }
 
 static int
-read_1_signed_byte (bfd *abfd, char *buf)
+read_1_signed_byte (bfd *abfd, gdb_byte *buf)
 {
-  return bfd_get_signed_8 (abfd, (bfd_byte *) buf);
+  return bfd_get_signed_8 (abfd, buf);
 }
 
 static unsigned int
-read_2_bytes (bfd *abfd, char *buf)
+read_2_bytes (bfd *abfd, gdb_byte *buf)
 {
-  return bfd_get_16 (abfd, (bfd_byte *) buf);
+  return bfd_get_16 (abfd, buf);
 }
 
 static int
-read_2_signed_bytes (bfd *abfd, char *buf)
+read_2_signed_bytes (bfd *abfd, gdb_byte *buf)
 {
-  return bfd_get_signed_16 (abfd, (bfd_byte *) buf);
+  return bfd_get_signed_16 (abfd, buf);
 }
 
 static unsigned int
-read_4_bytes (bfd *abfd, char *buf)
+read_4_bytes (bfd *abfd, gdb_byte *buf)
 {
-  return bfd_get_32 (abfd, (bfd_byte *) buf);
+  return bfd_get_32 (abfd, buf);
 }
 
 static int
-read_4_signed_bytes (bfd *abfd, char *buf)
+read_4_signed_bytes (bfd *abfd, gdb_byte *buf)
 {
-  return bfd_get_signed_32 (abfd, (bfd_byte *) buf);
+  return bfd_get_signed_32 (abfd, buf);
 }
 
 static unsigned long
-read_8_bytes (bfd *abfd, char *buf)
+read_8_bytes (bfd *abfd, gdb_byte *buf)
 {
-  return bfd_get_64 (abfd, (bfd_byte *) buf);
+  return bfd_get_64 (abfd, buf);
 }
 
 static CORE_ADDR
-read_address (bfd *abfd, char *buf, struct dwarf2_cu *cu, int *bytes_read)
+read_address (bfd *abfd, gdb_byte *buf, struct dwarf2_cu *cu,
+             unsigned int *bytes_read)
 {
   struct comp_unit_head *cu_header = &cu->header;
   CORE_ADDR retval = 0;
@@ -5346,17 +5866,17 @@ read_address (bfd *abfd, char *buf, struct dwarf2_cu *cu, int *bytes_read)
       switch (cu_header->addr_size)
        {
        case 2:
-         retval = bfd_get_signed_16 (abfd, (bfd_byte *) buf);
+         retval = bfd_get_signed_16 (abfd, buf);
          break;
        case 4:
-         retval = bfd_get_signed_32 (abfd, (bfd_byte *) buf);
+         retval = bfd_get_signed_32 (abfd, buf);
          break;
        case 8:
-         retval = bfd_get_signed_64 (abfd, (bfd_byte *) buf);
+         retval = bfd_get_signed_64 (abfd, buf);
          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));
        }
     }
@@ -5365,17 +5885,17 @@ read_address (bfd *abfd, char *buf, struct dwarf2_cu *cu, int *bytes_read)
       switch (cu_header->addr_size)
        {
        case 2:
-         retval = bfd_get_16 (abfd, (bfd_byte *) buf);
+         retval = bfd_get_16 (abfd, buf);
          break;
        case 4:
-         retval = bfd_get_32 (abfd, (bfd_byte *) buf);
+         retval = bfd_get_32 (abfd, buf);
          break;
        case 8:
-         retval = bfd_get_64 (abfd, (bfd_byte *) buf);
+         retval = bfd_get_64 (abfd, buf);
          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));
        }
     }
@@ -5398,18 +5918,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
@@ -5421,85 +5941,83 @@ 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
    ] */
 
 static LONGEST
-read_initial_length (bfd *abfd, char *buf, struct comp_unit_head *cu_header,
-                     int *bytes_read)
+read_initial_length (bfd *abfd, gdb_byte *buf, struct comp_unit_head *cu_header,
+                     unsigned int *bytes_read)
 {
-  LONGEST retval = 0;
-
-  retval = bfd_get_32 (abfd, (bfd_byte *) buf);
+  LONGEST length = bfd_get_32 (abfd, buf);
 
-  if (retval == 0xffffffff)
+  if (length == 0xffffffff)
     {
-      retval = bfd_get_64 (abfd, (bfd_byte *) buf + 4);
+      length = bfd_get_64 (abfd, 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, 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,
-             int *bytes_read)
+read_offset (bfd *abfd, gdb_byte *buf, const struct comp_unit_head *cu_header,
+             unsigned int *bytes_read)
 {
   LONGEST retval = 0;
 
   switch (cu_header->offset_size)
     {
     case 4:
-      retval = bfd_get_32 (abfd, (bfd_byte *) buf);
+      retval = bfd_get_32 (abfd, buf);
       *bytes_read = 4;
       break;
     case 8:
-      retval = bfd_get_64 (abfd, (bfd_byte *) buf);
+      retval = bfd_get_64 (abfd, buf);
       *bytes_read = 8;
       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 *
-read_n_bytes (bfd *abfd, char *buf, unsigned int size)
+static gdb_byte *
+read_n_bytes (bfd *abfd, gdb_byte *buf, unsigned int size)
 {
   /* If the size of a host char is 8 bits, we can return a pointer
      to the buffer, otherwise we have to copy the data to a buffer
@@ -5509,7 +6027,7 @@ read_n_bytes (bfd *abfd, char *buf, unsigned int size)
 }
 
 static char *
-read_string (bfd *abfd, char *buf, unsigned int *bytes_read_ptr)
+read_string (bfd *abfd, gdb_byte *buf, unsigned int *bytes_read_ptr)
 {
   /* If the size of a host char is 8 bits, we can return a pointer
      to the string, otherwise we have to copy the string to a buffer
@@ -5520,38 +6038,38 @@ read_string (bfd *abfd, char *buf, unsigned int *bytes_read_ptr)
       *bytes_read_ptr = 1;
       return NULL;
     }
-  *bytes_read_ptr = strlen (buf) + 1;
-  return buf;
+  *bytes_read_ptr = strlen ((char *) buf) + 1;
+  return (char *) buf;
 }
 
 static char *
-read_indirect_string (bfd *abfd, char *buf,
+read_indirect_string (bfd *abfd, gdb_byte *buf,
                      const struct comp_unit_head *cu_header,
                      unsigned int *bytes_read_ptr)
 {
   LONGEST str_offset = read_offset (abfd, buf, cu_header,
-                                   (int *) bytes_read_ptr);
+                                   bytes_read_ptr);
 
   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;
     }
   gdb_assert (HOST_CHAR_BIT == 8);
   if (dwarf2_per_objfile->str_buffer[str_offset] == '\0')
     return NULL;
-  return dwarf2_per_objfile->str_buffer + str_offset;
+  return (char *) (dwarf2_per_objfile->str_buffer + str_offset);
 }
 
 static unsigned long
-read_unsigned_leb128 (bfd *abfd, char *buf, unsigned int *bytes_read_ptr)
+read_unsigned_leb128 (bfd *abfd, gdb_byte *buf, unsigned int *bytes_read_ptr)
 {
   unsigned long result;
   unsigned int num_read;
@@ -5564,7 +6082,7 @@ read_unsigned_leb128 (bfd *abfd, char *buf, unsigned int *bytes_read_ptr)
   i = 0;
   while (1)
     {
-      byte = bfd_get_8 (abfd, (bfd_byte *) buf);
+      byte = bfd_get_8 (abfd, buf);
       buf++;
       num_read++;
       result |= ((unsigned long)(byte & 127) << shift);
@@ -5579,20 +6097,19 @@ read_unsigned_leb128 (bfd *abfd, char *buf, unsigned int *bytes_read_ptr)
 }
 
 static long
-read_signed_leb128 (bfd *abfd, char *buf, unsigned int *bytes_read_ptr)
+read_signed_leb128 (bfd *abfd, gdb_byte *buf, unsigned int *bytes_read_ptr)
 {
   long result;
-  int i, shift, size, num_read;
+  int i, shift, num_read;
   unsigned char byte;
 
   result = 0;
   shift = 0;
-  size = 32;
   num_read = 0;
   i = 0;
   while (1)
     {
-      byte = bfd_get_8 (abfd, (bfd_byte *) buf);
+      byte = bfd_get_8 (abfd, buf);
       buf++;
       num_read++;
       result |= ((long)(byte & 127) << shift);
@@ -5602,24 +6119,22 @@ read_signed_leb128 (bfd *abfd, char *buf, unsigned int *bytes_read_ptr)
          break;
        }
     }
-  if ((shift < size) && (byte & 0x40))
-    {
-      result |= -(1 << shift);
-    }
+  if ((shift < 8 * sizeof (result)) && (byte & 0x40))
+    result |= -(((long)1) << shift);
   *bytes_read_ptr = num_read;
   return result;
 }
 
 /* Return a pointer to just past the end of an LEB128 number in BUF.  */
 
-static char *
-skip_leb128 (bfd *abfd, char *buf)
+static gdb_byte *
+skip_leb128 (bfd *abfd, gdb_byte *buf)
 {
   int byte;
 
   while (1)
     {
-      byte = bfd_get_8 (abfd, (bfd_byte *) buf);
+      byte = bfd_get_8 (abfd, buf);
       buf++;
       if ((byte & 128) == 0)
        return buf;
@@ -5651,6 +6166,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:
@@ -5673,21 +6190,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;
 }
@@ -5729,7 +6239,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
@@ -5823,19 +6333,19 @@ dwarf_decode_line_header (unsigned int offset, bfd *abfd,
 {
   struct cleanup *back_to;
   struct line_header *lh;
-  char *line_ptr;
-  int bytes_read;
+  gdb_byte *line_ptr;
+  unsigned int bytes_read;
   int i;
   char *cur_dir, *cur_file;
 
   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 ();
@@ -5849,8 +6359,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))
@@ -5874,7 +6385,7 @@ dwarf_decode_line_header (unsigned int offset, bfd *abfd,
   lh->opcode_base = read_1_byte (abfd, line_ptr);
   line_ptr += 1;
   lh->standard_opcode_lengths
-    = (unsigned char *) xmalloc (lh->opcode_base * sizeof (unsigned char));
+    = xmalloc (lh->opcode_base * sizeof (lh->standard_opcode_lengths[0]));
 
   lh->standard_opcode_lengths[0] = 1;  /* This should never be used anyway.  */
   for (i = 1; i < lh->opcode_base; ++i)
@@ -5883,7 +6394,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;
@@ -5891,7 +6402,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;
@@ -5912,7 +6423,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;
@@ -5958,7 +6469,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;
@@ -5986,8 +6497,8 @@ static void
 dwarf_decode_lines (struct line_header *lh, char *comp_dir, bfd *abfd,
                    struct dwarf2_cu *cu, struct partial_symtab *pst)
 {
-  char *line_ptr;
-  char *line_end;
+  gdb_byte *line_ptr;
+  gdb_byte *line_end;
   unsigned int bytes_read;
   unsigned char op_code, extended_op, adj_opcode;
   CORE_ADDR baseaddr;
@@ -6019,6 +6530,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
@@ -6026,14 +6538,15 @@ 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;
@@ -6041,7 +6554,7 @@ dwarf_decode_lines (struct line_header *lh, char *comp_dir, bfd *abfd,
               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));
                 }
@@ -6088,7 +6601,7 @@ 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;
@@ -6110,11 +6623,12 @@ 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];
@@ -6138,9 +6652,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));
@@ -6150,8 +6664,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);
@@ -6171,9 +6687,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, (char *)NULL);
+                make_cleanup (xfree, include_name);
+              }
+
+            if (!IS_ABSOLUTE_PATH (pst_filename) && pst->dirname != NULL)
+              {
+                pst_filename = concat (pst->dirname, SLASH_STRING,
+                                      pst_filename, (char *)NULL);
+                make_cleanup (xfree, pst_filename);
+              }
+
+            if (strcmp (include_name, pst_filename) != 0)
               dwarf2_create_include_psymtab (include_name, pst, objfile);
           }
     }
@@ -6208,7 +6744,7 @@ dwarf2_start_subfile (char *filename, char *dirname)
   if (!IS_ABSOLUTE_PATH (filename) && dirname != NULL)
     {
       struct subfile *subfile;
-      char *fullname = concat (dirname, "/", filename, NULL);
+      char *fullname = concat (dirname, "/", filename, (char *)NULL);
 
       for (subfile = subfiles; subfile; subfile = subfile->next)
        {
@@ -6258,7 +6794,7 @@ var_decode_location (struct attribute *attr, struct symbol *sym,
       && DW_BLOCK (attr)->size == 1 + cu_header->addr_size
       && DW_BLOCK (attr)->data[0] == DW_OP_addr)
     {
-      int dummy;
+      unsigned int dummy;
 
       SYMBOL_VALUE_ADDRESS (sym) =
        read_address (objfile->obfd, DW_BLOCK (attr)->data + 1, cu, &dummy);
@@ -6431,7 +6967,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);
              
@@ -6448,7 +6985,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
@@ -6459,15 +6996,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,
@@ -6478,7 +7018,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);
              }
          }
@@ -6487,10 +7027,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;
@@ -6506,10 +7045,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)
@@ -6523,7 +7061,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);
@@ -6538,7 +7077,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;
        }
@@ -6564,7 +7103,7 @@ dwarf2_const_value (struct attribute *attr, struct symbol *sym,
                                                      cu_header->addr_size,
                                                      TYPE_LENGTH (SYMBOL_TYPE
                                                                   (sym)));
-      SYMBOL_VALUE_BYTES (sym) = (char *)
+      SYMBOL_VALUE_BYTES (sym) = 
        obstack_alloc (&objfile->objfile_obstack, cu_header->addr_size);
       /* NOTE: cagney/2003-05-09: In-lined store_address call with
          it's body - store_unsigned_integer.  */
@@ -6582,7 +7121,7 @@ dwarf2_const_value (struct attribute *attr, struct symbol *sym,
                                                      blk->size,
                                                      TYPE_LENGTH (SYMBOL_TYPE
                                                                   (sym)));
-      SYMBOL_VALUE_BYTES (sym) = (char *)
+      SYMBOL_VALUE_BYTES (sym) =
        obstack_alloc (&objfile->objfile_obstack, blk->size);
       memcpy (SYMBOL_VALUE_BYTES (sym), blk->data, blk->size);
       SYMBOL_CLASS (sym) = LOC_CONST_BYTES;
@@ -6618,7 +7157,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;
@@ -6657,7 +7196,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)
@@ -6666,21 +7204,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;
@@ -6695,49 +7225,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)
 {
@@ -6751,7 +7255,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;
@@ -6811,7 +7315,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;
     }
@@ -6832,7 +7336,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;
@@ -6856,9 +7361,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;
            }
@@ -6891,25 +7397,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 *
@@ -7067,21 +7595,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.  */
@@ -7910,7 +8429,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:
@@ -7918,13 +8437,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]));
@@ -7968,22 +8490,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
@@ -7994,18 +8510,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;
@@ -8027,28 +8541,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;
 }
 
@@ -8058,7 +8592,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);
     }
 
@@ -8093,9 +8627,6 @@ dwarf2_fundamental_type (struct objfile *objfile, int typeid,
    callers will only want a very basic result and this can become a
    complaint.
 
-   When the result is a register number, the global isreg flag is set,
-   otherwise it is cleared.
-
    Note that stack[0] is unused except as a default error return.
    Note that stack overflow is not yet handled.  */
 
@@ -8106,16 +8637,15 @@ decode_locdesc (struct dwarf_block *blk, struct dwarf2_cu *cu)
   struct comp_unit_head *cu_header = &cu->header;
   int i;
   int size = blk->size;
-  char *data = blk->data;
+  gdb_byte *data = blk->data;
   CORE_ADDR stack[64];
   int stacki;
   unsigned int bytes_read, unsnd;
-  unsigned char op;
+  gdb_byte op;
 
   i = 0;
   stacki = 0;
   stack[stacki] = 0;
-  isreg = 0;
 
   while (i < size)
     {
@@ -8189,14 +8719,12 @@ decode_locdesc (struct dwarf_block *blk, struct dwarf2_cu *cu)
        case DW_OP_reg29:
        case DW_OP_reg30:
        case DW_OP_reg31:
-         isreg = 1;
          stack[++stacki] = op - DW_OP_reg0;
          if (i < size)
            dwarf2_complex_location_expr_complaint ();
          break;
 
        case DW_OP_regx:
-         isreg = 1;
          unsnd = read_unsigned_leb128 (NULL, (data + i), &bytes_read);
          i += bytes_read;
          stack[++stacki] = unsnd;
@@ -8292,7 +8820,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]);
        }
@@ -8344,32 +8872,51 @@ dwarf_alloc_die (void)
 static char *
 file_full_name (int file, struct line_header *lh, const char *comp_dir)
 {
-  struct file_entry *fe = &lh->file_names[file - 1];
+  /* Is the file number a valid index into the line header's file name
+     table?  Remember that file numbers start with one, not zero.  */
+  if (1 <= file && file <= lh->num_file_names)
+    {
+      struct file_entry *fe = &lh->file_names[file - 1];
   
-  if (IS_ABSOLUTE_PATH (fe->name))
-    return xstrdup (fe->name);
+      if (IS_ABSOLUTE_PATH (fe->name))
+        return xstrdup (fe->name);
+      else
+        {
+          const char *dir;
+          int dir_len;
+          char *full_name;
+
+          if (fe->dir_index)
+            dir = lh->include_dirs[fe->dir_index - 1];
+          else
+            dir = comp_dir;
+
+          if (dir)
+            {
+              dir_len = strlen (dir);
+              full_name = xmalloc (dir_len + 1 + strlen (fe->name) + 1);
+              strcpy (full_name, dir);
+              full_name[dir_len] = '/';
+              strcpy (full_name + dir_len + 1, fe->name);
+              return full_name;
+            }
+          else
+            return xstrdup (fe->name);
+        }
+    }
   else
     {
-      const char *dir;
-      int dir_len;
-      char *full_name;
+      /* The compiler produced a bogus file number.  We can at least
+         record the macro definitions made in the file, even if we
+         won't be able to find the file by name.  */
+      char fake_name[80];
+      sprintf (fake_name, "<bad macro file number %d>", file);
 
-      if (fe->dir_index)
-        dir = lh->include_dirs[fe->dir_index - 1];
-      else
-        dir = comp_dir;
+      complaint (&symfile_complaints, 
+                 _("bad file number in macro information (%d)"),
+                 file);
 
-      if (dir)
-        {
-          dir_len = strlen (dir);
-          full_name = xmalloc (dir_len + 1 + strlen (fe->name) + 1);
-          strcpy (full_name, dir);
-          full_name[dir_len] = '/';
-          strcpy (full_name + dir_len + 1, fe->name);
-          return full_name;
-        }
-      else
-        return xstrdup (fe->name);
+      return xstrdup (fake_name);
     }
 }
 
@@ -8421,7 +8968,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 == ' ')
@@ -8578,12 +9125,12 @@ dwarf_decode_macros (struct line_header *lh, unsigned int offset,
                      char *comp_dir, bfd *abfd,
                      struct dwarf2_cu *cu)
 {
-  char *mac_ptr, *mac_end;
+  gdb_byte *mac_ptr, *mac_end;
   struct macro_source_file *current_file = 0;
 
   if (dwarf2_per_objfile->macinfo_buffer == NULL)
     {
-      complaint (&symfile_complaints, "missing .debug_macinfo section");
+      complaint (&symfile_complaints, _("missing .debug_macinfo section"));
       return;
     }
 
@@ -8615,7 +9162,7 @@ dwarf_decode_macros (struct line_header *lh, unsigned int offset,
         case DW_MACINFO_define:
         case DW_MACINFO_undef:
           {
-            int bytes_read;
+            unsigned int bytes_read;
             int line;
             char *body;
 
@@ -8626,7 +9173,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" :
@@ -8643,7 +9190,7 @@ dwarf_decode_macros (struct line_header *lh, unsigned int offset,
 
         case DW_MACINFO_start_file:
           {
-            int bytes_read;
+            unsigned int bytes_read;
             int line, file;
 
             line = read_unsigned_leb128 (abfd, mac_ptr, &bytes_read);
@@ -8660,7 +9207,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;
@@ -8685,7 +9232,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;
                 }
@@ -8694,7 +9241,7 @@ dwarf_decode_macros (struct line_header *lh, unsigned int offset,
 
         case DW_MACINFO_vendor_ext:
           {
-            int bytes_read;
+            unsigned int bytes_read;
             int constant;
             char *string;
 
@@ -8741,7 +9288,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;
@@ -8777,9 +9324,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.  */
 
@@ -8790,28 +9413,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;
+    }
 }
 
-/* Allocation function for the libiberty hash table which uses an
-   obstack.  */
+/* 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.  */
 
-static void *
-hashtab_obstack_allocate (void *data, size_t size, size_t count)
+struct dwarf2_offset_and_type
 {
-  unsigned int total = size * count;
-  void *ptr = obstack_alloc ((struct obstack *) data, total);
-  memset (ptr, 0, total);
-  return ptr;
+  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;
 }
 
-/* Trivial deallocation function for the libiberty splay tree and hash
-   table - don't deallocate anything.  Rely on later deletion of the
-   obstack.  */
+/* Set the type associated with DIE to TYPE.  Save it in CU's hash
+   table if necessary.  */
 
 static void
-dummy_obstack_deallocate (void *object, void *data)
+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)
 {
-  return;
+  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;
+    }
 }
 
 /* Trivial hash function for partial_die_info: the hash value of a DIE
@@ -8835,10 +9693,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.083789 seconds and 4 git commands to generate.