Mirror of the gdb-patches mailing list
 help / color / mirror / Atom feed
From: Paul Pluzhnikov <ppluzhnikov@google.com>
To: tromey@redhat.com
Cc: gdb-patches@sources.redhat.com
Subject: Re: [patch] Use mmap instead of obstack_alloc for dwarf debug  	sections.
Date: Tue, 16 Jun 2009 20:43:00 -0000	[thread overview]
Message-ID: <8ac60eac0906161342m67c30151lc7f685e0eb36e41f@mail.gmail.com> (raw)
In-Reply-To: <m3zlc80yxc.fsf@fleche.redhat.com>

[-- Attachment #1: Type: text/plain, Size: 2668 bytes --]

On Tue, Jun 16, 2009 at 12:19 PM, Tom Tromey<tromey@redhat.com> wrote:

> Thanks.  One point of order -- if you re-send a patch, re-send the
> ChangeLog entry too.  Not a big deal, but it makes things simpler when
> reviewing.  Thanks.

Will do, thanks.

> I saw in your original post that this patch helps on
> memory-constrained machines; your example was 2G of debug info on a 4G
> machine. I just want to make sure that this doesn't hurt other cases;
> I don't expect it would, but it is good to cross the t's...

I saw minor gain on 16GB machine.

I don't see how this could hurt: we aren't using any more memory by doing
mmap, we just cooperate with buffer cache instead of fighting with it.

>
> Paul> + int was_mmaped;
>
> I would spell this "was_mmapped" (two "p"s).

Fixed.

> Paul> + /* When debugging .o files, we may need to apply relocations; see
> Paul> +    http://sourceware.org/ml/gdb-patches/2002-04/msg00136.html .
> Paul> +    We never compress sections in .o files, so we only need to
> Paul> +    try this when the section is not compressed.  */
> Paul> +  retbuf = symfile_relocate_debug_section (abfd, sectp, buf);
>
> If we're using mmap then we seem to skip this relocation step.
> This seems like a bug.

That's what "&& (sectp->flags & SEC_RELOC) == 0)" check before mmap is for.
In symfile_relocate_debug_section():

  /* We're only interested in sections with relocation
     information.  */
  if ((sectp->flags & SEC_RELOC) == 0)
    return NULL;

I've added a comment to that effect.

> IIUC, this is an unusual case. So perhaps one fix would be to
> introduce a new symfile_debug_section_needs_relocate_p, then protect
> the mmap branch with that.

I can add symfile_debug_section_needs_relocate_p() if that's preferable.

> Paul> + gdb_assert (munmap ((void *)map_begin, map_length) == 0);
>
> Space after the ")" of the cast to void *.

Fixed.

Thanks,
-- 
Paul Pluzhnikov

2009-06-16  Paul Pluzhnikov  <ppluzhnikov@google.com>

       * dwarf2read.c (dwarf_info_section, dwarf_abbrev_section)
       (dwarf_line_section, dwarf_pubnames_section, dwarf_aranges_section)
       (dwarf_loc_section, dwarf_macinfo_section, dwarf_str_section)
       (dwarf_ranges_section, dwarf_frame_section,
dwarf_eh_frame_section): Removed.
       (dwarf2_resize_section): Likewise.
       (dwarf2_read_section): Now static, use bfd_mmap() if possible.
       (dwarf2_get_section_info): New function.
       (munmap_section_buffer): Likewise.
       (dwarf2_per_objfile_cleanup): Likewise.
       (section_is_p): Signature change.
       * dwarf2-frame.c (dwarf2_build_frame_info): Use
       dwarf2_get_section_info instead of dwarf2_read_section.

[-- Attachment #2: gdb-dwarf2-mmap-20090616.txt --]
[-- Type: text/plain, Size: 43784 bytes --]

Index: dwarf2read.c
===================================================================
RCS file: /cvs/src/src/gdb/dwarf2read.c,v
retrieving revision 1.308
diff -u -p -u -r1.308 dwarf2read.c
--- dwarf2read.c	13 Jun 2009 04:23:34 -0000	1.308
+++ dwarf2read.c	16 Jun 2009 20:41:52 -0000
@@ -55,20 +55,9 @@
 #ifdef HAVE_ZLIB_H
 #include <zlib.h>
 #endif
-
-/* A note on memory usage for this file.
-   
-   At the present time, this code reads the debug info sections into
-   the objfile's objfile_obstack.  A definite improvement for startup
-   time, on platforms which do not emit relocations for debug
-   sections, would be to use mmap instead.  The object's complete
-   debug information is loaded into memory, partly to simplify
-   absolute DIE references.
-
-   Whether using obstacks or mmap, the sections should remain loaded
-   until the objfile is released, and pointers into the section data
-   can be used for any other data associated to the objfile (symbol
-   names, type names, location expressions to name a few).  */
+#ifdef HAVE_MMAP
+#include <sys/mman.h>
+#endif
 
 #if 0
 /* .debug_info header for a compilation unit
@@ -145,6 +134,8 @@ _STATEMENT_PROLOGUE;
 /* When non-zero, dump DIEs after they are read in.  */
 static int dwarf2_die_debug = 0;
 
+static int pagesize;
+
 /* When set, the file that we're processing is known to have debugging
    info for C++ namespaces.  GCC 3.3.x did not produce this information,
    but later versions do.  */
@@ -153,29 +144,27 @@ static int processing_has_namespace_info
 
 static const struct objfile_data *dwarf2_objfile_data_key;
 
+struct dwarf2_section_info
+{
+  asection *asection;
+  gdb_byte *buffer;
+  bfd_size_type size;
+  int was_mmapped;
+};
+
 struct dwarf2_per_objfile
 {
-  /* Sizes of debugging sections.  */
-  unsigned int info_size;
-  unsigned int abbrev_size;
-  unsigned int line_size;
-  unsigned int pubnames_size;
-  unsigned int aranges_size;
-  unsigned int loc_size;
-  unsigned int macinfo_size;
-  unsigned int str_size;
-  unsigned int ranges_size;
-  unsigned int frame_size;
-  unsigned int eh_frame_size;
-
-  /* Loaded data from the sections.  */
-  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;
+  struct dwarf2_section_info info;
+  struct dwarf2_section_info abbrev;
+  struct dwarf2_section_info line;
+  struct dwarf2_section_info pubnames;
+  struct dwarf2_section_info aranges;
+  struct dwarf2_section_info loc;
+  struct dwarf2_section_info macinfo;
+  struct dwarf2_section_info str;
+  struct dwarf2_section_info ranges;
+  struct dwarf2_section_info frame;
+  struct dwarf2_section_info eh_frame;
 
   /* A list of all the compilation units.  This is used to locate
      the target compilation unit of a particular reference.  */
@@ -195,18 +184,6 @@ struct dwarf2_per_objfile
 
 static struct dwarf2_per_objfile *dwarf2_per_objfile;
 
-static asection *dwarf_info_section;
-static asection *dwarf_abbrev_section;
-static asection *dwarf_line_section;
-static asection *dwarf_pubnames_section;
-static asection *dwarf_aranges_section;
-static asection *dwarf_loc_section;
-static asection *dwarf_macinfo_section;
-static asection *dwarf_str_section;
-static asection *dwarf_ranges_section;
-asection *dwarf_frame_section;
-asection *dwarf_eh_frame_section;
-
 /* names of the debugging sections */
 
 /* Note that if the debugging section has been compressed, it might
@@ -803,8 +780,6 @@ static void dwarf2_psymtab_to_symtab (st
 
 static void psymtab_to_symtab_1 (struct partial_symtab *);
 
-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 *);
@@ -1130,30 +1105,20 @@ dwarf2_has_info (struct objfile *objfile
   set_objfile_data (objfile, dwarf2_objfile_data_key, data);
   dwarf2_per_objfile = data;
 
-  dwarf_info_section = 0;
-  dwarf_abbrev_section = 0;
-  dwarf_line_section = 0;
-  dwarf_str_section = 0;
-  dwarf_macinfo_section = 0;
-  dwarf_frame_section = 0;
-  dwarf_eh_frame_section = 0;
-  dwarf_ranges_section = 0;
-  dwarf_loc_section = 0;
-  
   bfd_map_over_sections (objfile->obfd, dwarf2_locate_sections, NULL);
-  return (dwarf_info_section != NULL && dwarf_abbrev_section != NULL);
+  return (data->info.asection != NULL && data->abbrev.asection != NULL);
 }
 
 /* When loading sections, we can either look for ".<name>", or for
  * ".z<name>", which indicates a compressed section.  */
 
 static int
-section_is_p (asection *sectp, const char *name)
+section_is_p (const char *section_name, const char *name)
 {
-  return ((sectp->name[0] == '.'
-           && strcmp (sectp->name + 1, name) == 0)
-          || (sectp->name[0] == '.' && sectp->name[1] == 'z'
-              && strcmp (sectp->name + 2, name) == 0));
+  return (section_name[0] == '.'
+	  && (strcmp (section_name + 1, name) == 0
+	      || (section_name[1] == 'z'
+		  && strcmp (section_name + 2, name) == 0)));
 }
 
 /* This function is mapped across the sections and remembers the
@@ -1163,140 +1128,266 @@ section_is_p (asection *sectp, const cha
 static void
 dwarf2_locate_sections (bfd *abfd, asection *sectp, void *ignore_ptr)
 {
-  if (section_is_p (sectp, INFO_SECTION))
+  if (section_is_p (sectp->name, INFO_SECTION))
     {
-      dwarf2_per_objfile->info_size = bfd_get_section_size (sectp);
-      dwarf_info_section = sectp;
+      dwarf2_per_objfile->info.asection = sectp;
+      dwarf2_per_objfile->info.size = bfd_get_section_size (sectp);
     }
-  else if (section_is_p (sectp, ABBREV_SECTION))
+  else if (section_is_p (sectp->name, ABBREV_SECTION))
     {
-      dwarf2_per_objfile->abbrev_size = bfd_get_section_size (sectp);
-      dwarf_abbrev_section = sectp;
+      dwarf2_per_objfile->abbrev.asection = sectp;
+      dwarf2_per_objfile->abbrev.size = bfd_get_section_size (sectp);
     }
-  else if (section_is_p (sectp, LINE_SECTION))
+  else if (section_is_p (sectp->name, LINE_SECTION))
     {
-      dwarf2_per_objfile->line_size = bfd_get_section_size (sectp);
-      dwarf_line_section = sectp;
+      dwarf2_per_objfile->line.asection = sectp;
+      dwarf2_per_objfile->line.size = bfd_get_section_size (sectp);
     }
-  else if (section_is_p (sectp, PUBNAMES_SECTION))
+  else if (section_is_p (sectp->name, PUBNAMES_SECTION))
     {
-      dwarf2_per_objfile->pubnames_size = bfd_get_section_size (sectp);
-      dwarf_pubnames_section = sectp;
+      dwarf2_per_objfile->pubnames.asection = sectp;
+      dwarf2_per_objfile->pubnames.size = bfd_get_section_size (sectp);
     }
-  else if (section_is_p (sectp, ARANGES_SECTION))
+  else if (section_is_p (sectp->name, ARANGES_SECTION))
     {
-      dwarf2_per_objfile->aranges_size = bfd_get_section_size (sectp);
-      dwarf_aranges_section = sectp;
+      dwarf2_per_objfile->aranges.asection = sectp;
+      dwarf2_per_objfile->aranges.size = bfd_get_section_size (sectp);
     }
-  else if (section_is_p (sectp, LOC_SECTION))
+  else if (section_is_p (sectp->name, LOC_SECTION))
     {
-      dwarf2_per_objfile->loc_size = bfd_get_section_size (sectp);
-      dwarf_loc_section = sectp;
+      dwarf2_per_objfile->loc.asection = sectp;
+      dwarf2_per_objfile->loc.size = bfd_get_section_size (sectp);
     }
-  else if (section_is_p (sectp, MACINFO_SECTION))
+  else if (section_is_p (sectp->name, MACINFO_SECTION))
     {
-      dwarf2_per_objfile->macinfo_size = bfd_get_section_size (sectp);
-      dwarf_macinfo_section = sectp;
+      dwarf2_per_objfile->macinfo.asection = sectp;
+      dwarf2_per_objfile->macinfo.size = bfd_get_section_size (sectp);
     }
-  else if (section_is_p (sectp, STR_SECTION))
+  else if (section_is_p (sectp->name, STR_SECTION))
     {
-      dwarf2_per_objfile->str_size = bfd_get_section_size (sectp);
-      dwarf_str_section = sectp;
+      dwarf2_per_objfile->str.asection = sectp;
+      dwarf2_per_objfile->str.size = bfd_get_section_size (sectp);
     }
-  else if (section_is_p (sectp, FRAME_SECTION))
+  else if (section_is_p (sectp->name, FRAME_SECTION))
     {
-      dwarf2_per_objfile->frame_size = bfd_get_section_size (sectp);
-      dwarf_frame_section = sectp;
+      dwarf2_per_objfile->frame.asection = sectp;
+      dwarf2_per_objfile->frame.size = bfd_get_section_size (sectp);
     }
-  else if (section_is_p (sectp, EH_FRAME_SECTION))
+  else if (section_is_p (sectp->name, EH_FRAME_SECTION))
     {
       flagword aflag = bfd_get_section_flags (ignore_abfd, sectp);
       if (aflag & SEC_HAS_CONTENTS)
         {
-          dwarf2_per_objfile->eh_frame_size = bfd_get_section_size (sectp);
-          dwarf_eh_frame_section = sectp;
+	  dwarf2_per_objfile->eh_frame.asection = sectp;
+          dwarf2_per_objfile->eh_frame.size = bfd_get_section_size (sectp);
         }
     }
-  else if (section_is_p (sectp, RANGES_SECTION))
+  else if (section_is_p (sectp->name, RANGES_SECTION))
     {
-      dwarf2_per_objfile->ranges_size = bfd_get_section_size (sectp);
-      dwarf_ranges_section = sectp;
+      dwarf2_per_objfile->ranges.asection = sectp;
+      dwarf2_per_objfile->ranges.size = bfd_get_section_size (sectp);
     }
-  
+
   if ((bfd_get_section_flags (abfd, sectp) & SEC_LOAD)
       && bfd_section_vma (abfd, sectp) == 0)
     dwarf2_per_objfile->has_section_at_zero = 1;
 }
 
-/* This function is called after decompressing a section, so
-   dwarf2_per_objfile can record its new, uncompressed size.  */
+/* Decompress a section that was compressed using zlib.  Store the
+   decompressed buffer, and its size, in OUTBUF and OUTSIZE.  */
 
 static void
-dwarf2_resize_section (asection *sectp, bfd_size_type new_size)
+zlib_decompress_section (struct objfile *objfile, asection *sectp,
+                         gdb_byte **outbuf, bfd_size_type *outsize)
 {
-  if (section_is_p (sectp, INFO_SECTION))
-    dwarf2_per_objfile->info_size = new_size;
-  else if (section_is_p (sectp, ABBREV_SECTION))
-    dwarf2_per_objfile->abbrev_size = new_size;
-  else if (section_is_p (sectp, LINE_SECTION))
-    dwarf2_per_objfile->line_size = new_size;
-  else if (section_is_p (sectp, PUBNAMES_SECTION))
-    dwarf2_per_objfile->pubnames_size = new_size;
-  else if (section_is_p (sectp, ARANGES_SECTION))
-    dwarf2_per_objfile->aranges_size = new_size;
-  else if (section_is_p (sectp, LOC_SECTION))
-    dwarf2_per_objfile->loc_size = new_size;
-  else if (section_is_p (sectp, MACINFO_SECTION))
-    dwarf2_per_objfile->macinfo_size = new_size;
-  else if (section_is_p (sectp, STR_SECTION))
-    dwarf2_per_objfile->str_size = new_size;
-  else if (section_is_p (sectp, FRAME_SECTION))
-    dwarf2_per_objfile->frame_size = new_size;
-  else if (section_is_p (sectp, EH_FRAME_SECTION))
-    dwarf2_per_objfile->eh_frame_size = new_size;
-  else if (section_is_p (sectp, RANGES_SECTION))
-    dwarf2_per_objfile->ranges_size = new_size;
-  else
-    internal_error (__FILE__, __LINE__,
-		    _("dwarf2_resize_section: missing section_is_p check: %s"),
-                    sectp->name);
+  bfd *abfd = objfile->obfd;
+#ifndef HAVE_ZLIB_H
+  error (_("Support for zlib-compressed DWARF data (from '%s') "
+           "is disabled in this copy of GDB"),
+         bfd_get_filename (abfd));
+#else
+  bfd_size_type compressed_size = bfd_get_section_size (sectp);
+  gdb_byte *compressed_buffer = xmalloc (compressed_size);
+  bfd_size_type uncompressed_size;
+  gdb_byte *uncompressed_buffer;
+  z_stream strm;
+  int rc;
+  int header_size = 12;
+
+  if (bfd_seek (abfd, sectp->filepos, SEEK_SET) != 0
+      || bfd_bread (compressed_buffer, compressed_size, abfd) != compressed_size)
+    error (_("Dwarf Error: Can't read DWARF data from '%s'"),
+           bfd_get_filename (abfd));
+
+  /* Read the zlib header.  In this case, it should be "ZLIB" followed
+     by the uncompressed section size, 8 bytes in big-endian order.  */
+  if (compressed_size < header_size
+      || strncmp (compressed_buffer, "ZLIB", 4) != 0)
+    error (_("Dwarf Error: Corrupt DWARF ZLIB header from '%s'"),
+           bfd_get_filename (abfd));
+  uncompressed_size = compressed_buffer[4]; uncompressed_size <<= 8;
+  uncompressed_size += compressed_buffer[5]; uncompressed_size <<= 8;
+  uncompressed_size += compressed_buffer[6]; uncompressed_size <<= 8;
+  uncompressed_size += compressed_buffer[7]; uncompressed_size <<= 8;
+  uncompressed_size += compressed_buffer[8]; uncompressed_size <<= 8;
+  uncompressed_size += compressed_buffer[9]; uncompressed_size <<= 8;
+  uncompressed_size += compressed_buffer[10]; uncompressed_size <<= 8;
+  uncompressed_size += compressed_buffer[11];
+
+  /* It is possible the section consists of several compressed
+     buffers concatenated together, so we uncompress in a loop.  */
+  strm.zalloc = NULL;
+  strm.zfree = NULL;
+  strm.opaque = NULL;
+  strm.avail_in = compressed_size - header_size;
+  strm.next_in = (Bytef*) compressed_buffer + header_size;
+  strm.avail_out = uncompressed_size;
+  uncompressed_buffer = obstack_alloc (&objfile->objfile_obstack,
+                                       uncompressed_size);
+  rc = inflateInit (&strm);
+  while (strm.avail_in > 0)
+    {
+      if (rc != Z_OK)
+        error (_("Dwarf Error: setting up DWARF uncompression in '%s': %d"),
+               bfd_get_filename (abfd), rc);
+      strm.next_out = ((Bytef*) uncompressed_buffer
+                       + (uncompressed_size - strm.avail_out));
+      rc = inflate (&strm, Z_FINISH);
+      if (rc != Z_STREAM_END)
+        error (_("Dwarf Error: zlib error uncompressing from '%s': %d"),
+               bfd_get_filename (abfd), rc);
+      rc = inflateReset (&strm);
+    }
+  rc = inflateEnd (&strm);
+  if (rc != Z_OK
+      || strm.avail_out != 0)
+    error (_("Dwarf Error: concluding DWARF uncompression in '%s': %d"),
+           bfd_get_filename (abfd), rc);
+
+  xfree (compressed_buffer);
+  *outbuf = uncompressed_buffer;
+  *outsize = uncompressed_size;
+#endif
 }
 
-/* Build a partial symbol table.  */
+/* Read the contents of the section SECTP from object file specified by
+   OBJFILE, store info about the section into INFO.
+   If the section is compressed, uncompress it before returning.  */
 
-void
-dwarf2_build_psymtabs (struct objfile *objfile, int mainline)
+static void
+dwarf2_read_section (struct objfile *objfile, struct dwarf2_section_info *info)
 {
-  /* We definitely need the .debug_info and .debug_abbrev sections */
+  bfd *abfd = objfile->obfd;
+  asection *sectp = info->asection;
+  gdb_byte *buf, *retbuf;
+  unsigned char header[4];
 
-  dwarf2_per_objfile->info_buffer = dwarf2_read_section (objfile, dwarf_info_section);
-  dwarf2_per_objfile->abbrev_buffer = dwarf2_read_section (objfile, dwarf_abbrev_section);
+  info->buffer = NULL;
+  info->was_mmapped = 0;
 
-  if (dwarf_line_section)
-    dwarf2_per_objfile->line_buffer = dwarf2_read_section (objfile, dwarf_line_section);
-  else
-    dwarf2_per_objfile->line_buffer = NULL;
+  if (info->asection == NULL || info->size == 0)
+    return;
 
-  if (dwarf_str_section)
-    dwarf2_per_objfile->str_buffer = dwarf2_read_section (objfile, dwarf_str_section);
-  else
-    dwarf2_per_objfile->str_buffer = NULL;
+  /* Check if the file has a 4-byte header indicating compression.  */
+  if (info->size > sizeof (header)
+      && bfd_seek (abfd, sectp->filepos, SEEK_SET) == 0
+      && bfd_bread (header, sizeof (header), abfd) == sizeof (header))
+    {
+      /* Upon decompression, update the buffer and its size.  */
+      if (strncmp (header, "ZLIB", sizeof (header)) == 0)
+        {
+          zlib_decompress_section (objfile, sectp, &info->buffer,
+				   &info->size);
+          return;
+        }
+    }
 
-  if (dwarf_macinfo_section)
-    dwarf2_per_objfile->macinfo_buffer = dwarf2_read_section (objfile,
-						dwarf_macinfo_section);
-  else
-    dwarf2_per_objfile->macinfo_buffer = NULL;
+#ifdef HAVE_MMAP
+  if (pagesize == 0)
+    pagesize = getpagesize ();
 
-  if (dwarf_ranges_section)
-    dwarf2_per_objfile->ranges_buffer = dwarf2_read_section (objfile, dwarf_ranges_section);
-  else
-    dwarf2_per_objfile->ranges_buffer = NULL;
+  /* Only try to mmap sections which are large enough: we don't want to
+     waste space due to fragmentation.  Also, only try mmap for sections
+     without relocations.  */
 
-  if (dwarf_loc_section)
-    dwarf2_per_objfile->loc_buffer = dwarf2_read_section (objfile, dwarf_loc_section);
-  else
-    dwarf2_per_objfile->loc_buffer = NULL;
+  if (info->size > 4 * pagesize && (sectp->flags & SEC_RELOC) == 0)
+    {
+      off_t pg_offset = sectp->filepos & ~(pagesize - 1);
+      size_t map_length = info->size + sectp->filepos - pg_offset;
+      caddr_t retbuf = bfd_mmap (abfd, 0, map_length, PROT_READ,
+				 MAP_PRIVATE, pg_offset);
+
+      if (retbuf != MAP_FAILED)
+	{
+	  info->was_mmapped = 1;
+	  info->buffer = retbuf + (sectp->filepos & (pagesize - 1)) ;
+	  return;
+	}
+    }
+#endif
+
+  /* If we get here, we are a normal, not-compressed section.  */
+  info->buffer = buf
+    = obstack_alloc (&objfile->objfile_obstack, info->size);
+
+  /* When debugging .o files, we may need to apply relocations; see
+     http://sourceware.org/ml/gdb-patches/2002-04/msg00136.html .
+     We never compress sections in .o files, so we only need to
+     try this when the section is not compressed.  */
+  retbuf = symfile_relocate_debug_section (abfd, sectp, buf);
+  if (retbuf != NULL)
+    {
+      info->buffer = retbuf;
+      return;
+    }
+
+  if (bfd_seek (abfd, sectp->filepos, SEEK_SET) != 0
+      || bfd_bread (buf, info->size, abfd) != info->size)
+    error (_("Dwarf Error: Can't read DWARF data from '%s'"),
+	   bfd_get_filename (abfd));
+}
+
+/* Fill in SECTP, BUFP and SIZEP with section info, given OBJFILE and
+   SECTION_NAME. */
+
+void
+dwarf2_get_section_info (struct objfile *objfile, const char *section_name,
+                         asection **sectp, gdb_byte **bufp,
+                         bfd_size_type *sizep)
+{
+  struct dwarf2_per_objfile *data
+    = objfile_data (objfile, dwarf2_objfile_data_key);
+  struct dwarf2_section_info *info;
+  if (section_is_p (section_name, EH_FRAME_SECTION))
+    info = &data->eh_frame;
+  else if (section_is_p (section_name, FRAME_SECTION))
+    info = &data->frame;
+  else
+    gdb_assert (0);
+
+  if (info->asection != NULL && info->size != 0 && info->buffer == NULL)
+    /* We haven't read this section in yet.  Do it now.  */
+    dwarf2_read_section (objfile, info);
+
+  *sectp = info->asection;
+  *bufp = info->buffer;
+  *sizep = info->size;
+}
+
+/* Build a partial symbol table.  */
+
+void
+dwarf2_build_psymtabs (struct objfile *objfile, int mainline)
+{
+  dwarf2_read_section (objfile, &dwarf2_per_objfile->info);
+  dwarf2_read_section (objfile, &dwarf2_per_objfile->abbrev);
+  dwarf2_read_section (objfile, &dwarf2_per_objfile->line);
+  dwarf2_read_section (objfile, &dwarf2_per_objfile->str);
+  dwarf2_read_section (objfile, &dwarf2_per_objfile->macinfo);
+  dwarf2_read_section (objfile, &dwarf2_per_objfile->ranges);
+  dwarf2_read_section (objfile, &dwarf2_per_objfile->loc);
+  dwarf2_read_section (objfile, &dwarf2_per_objfile->eh_frame);
+  dwarf2_read_section (objfile, &dwarf2_per_objfile->frame);
 
   if (mainline
       || (objfile->global_psymbols.size == 0
@@ -1337,7 +1428,7 @@ dwarf2_build_psymtabs_easy (struct objfi
   pubnames_buffer = dwarf2_read_section (objfile,
 					 dwarf_pubnames_section);
   pubnames_ptr = pubnames_buffer;
-  while ((pubnames_ptr - pubnames_buffer) < dwarf2_per_objfile->pubnames_size)
+  while ((pubnames_ptr - pubnames_buffer) < dwarf2_per_objfile->pubnames.size)
     {
       unsigned int bytes_read;
 
@@ -1412,19 +1503,19 @@ partial_read_comp_unit_head (struct comp
 	   "(is %d, should be %d) [in module %s]"), header->version,
 	   2, bfd_get_filename (abfd));
 
-  if (header->abbrev_offset >= dwarf2_per_objfile->abbrev_size)
+  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]"),
 	   (long) header->abbrev_offset,
-	   (long) (beg_of_comp_unit - dwarf2_per_objfile->info_buffer),
+	   (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)
+      > 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]"),
 	   (long) header->length,
-	   (long) (beg_of_comp_unit - dwarf2_per_objfile->info_buffer),
+	   (long) (beg_of_comp_unit - dwarf2_per_objfile->info.buffer),
 	   bfd_get_filename (abfd));
 
   return info_ptr;
@@ -1506,7 +1597,7 @@ dwarf2_build_psymtabs_hard (struct objfi
   struct cleanup *back_to;
   CORE_ADDR baseaddr;
 
-  info_ptr = dwarf2_per_objfile->info_buffer;
+  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.  */
@@ -1530,8 +1621,8 @@ dwarf2_build_psymtabs_hard (struct objfi
 
      For this loop condition, simply checking whether there's any data
      left at all should be sufficient.  */
-  while (info_ptr < (dwarf2_per_objfile->info_buffer
-		     + dwarf2_per_objfile->info_size))
+  while (info_ptr < (dwarf2_per_objfile->info.buffer
+		     + dwarf2_per_objfile->info.size))
     {
       struct cleanup *back_to_inner;
       struct dwarf2_cu cu;
@@ -1551,7 +1642,7 @@ dwarf2_build_psymtabs_hard (struct objfi
       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.offset = beg_of_comp_unit - dwarf2_per_objfile->info.buffer;
       cu.header.first_die_offset = info_ptr - beg_of_comp_unit;
 
       cu.list_in_scope = &file_symbols;
@@ -1708,7 +1799,7 @@ load_comp_unit (struct dwarf2_per_cu_dat
   unsigned int bytes_read;
   struct cleanup *back_to;
 
-  info_ptr = dwarf2_per_objfile->info_buffer + this_cu->offset;
+  info_ptr = dwarf2_per_objfile->info.buffer + this_cu->offset;
   beg_of_comp_unit = info_ptr;
 
   cu = xmalloc (sizeof (struct dwarf2_cu));
@@ -1720,7 +1811,7 @@ load_comp_unit (struct dwarf2_per_cu_dat
   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.offset = beg_of_comp_unit - dwarf2_per_objfile->info.buffer;
   cu->header.first_die_offset = info_ptr - beg_of_comp_unit;
 
   /* Read the abbrevs for this compilation unit into a table.  */
@@ -1760,21 +1851,21 @@ create_all_comp_units (struct objfile *o
   int n_allocated;
   int n_comp_units;
   struct dwarf2_per_cu_data **all_comp_units;
-  gdb_byte *info_ptr = dwarf2_per_objfile->info_buffer;
+  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)
+  while (info_ptr < dwarf2_per_objfile->info.buffer + dwarf2_per_objfile->info.size)
     {
       unsigned int length, initial_length_size;
       gdb_byte *beg_of_comp_unit;
       struct dwarf2_per_cu_data *this_cu;
       unsigned int offset;
 
-      offset = info_ptr - dwarf2_per_objfile->info_buffer;
+      offset = info_ptr - dwarf2_per_objfile->info.buffer;
 
       /* Read just enough information to find out where the next
 	 compilation unit is.  */
@@ -2420,7 +2511,7 @@ skip_one_die (gdb_byte *info_ptr, struct
 	  if (attr.form == DW_FORM_ref_addr)
 	    complaint (&symfile_complaints, _("ignoring absolute DW_AT_sibling"));
 	  else
-	    return dwarf2_per_objfile->info_buffer
+	    return dwarf2_per_objfile->info.buffer
 	      + dwarf2_get_ref_die_offset (&attr);
 	}
 
@@ -2706,7 +2797,7 @@ load_full_comp_unit (struct dwarf2_per_c
   /* Set local variables from the partial symbol table info.  */
   offset = per_cu->offset;
 
-  info_ptr = dwarf2_per_objfile->info_buffer + offset;
+  info_ptr = dwarf2_per_objfile->info.buffer + offset;
 
   cu = xmalloc (sizeof (struct dwarf2_cu));
   memset (cu, 0, sizeof (struct dwarf2_cu));
@@ -3371,14 +3462,14 @@ dwarf2_ranges_read (unsigned offset, COR
   found_base = cu->base_known;
   base = cu->base_address;
 
-  if (offset >= dwarf2_per_objfile->ranges_size)
+  if (offset >= dwarf2_per_objfile->ranges.size)
     {
       complaint (&symfile_complaints,
 		 _("Offset %d out of bounds for DW_AT_ranges attribute"),
 		 offset);
       return 0;
     }
-  buffer = dwarf2_per_objfile->ranges_buffer + offset;
+  buffer = dwarf2_per_objfile->ranges.buffer + offset;
 
   /* Read in the largest possible address.  */
   marker = read_address (obfd, buffer, cu, &dummy);
@@ -3653,7 +3744,7 @@ dwarf2_record_block_ranges (struct die_i
       /* The value of the DW_AT_ranges attribute is the offset of the
          address range list in the .debug_ranges section.  */
       unsigned long offset = DW_UNSND (attr);
-      gdb_byte *buffer = dwarf2_per_objfile->ranges_buffer + offset;
+      gdb_byte *buffer = dwarf2_per_objfile->ranges.buffer + offset;
 
       /* For some target architectures, but not others, the
          read_address function sign-extends the addresses it returns.
@@ -3672,7 +3763,7 @@ dwarf2_record_block_ranges (struct die_i
       CORE_ADDR base = cu->base_address;
       int base_known = cu->base_known;
 
-      if (offset >= dwarf2_per_objfile->ranges_size)
+      if (offset >= dwarf2_per_objfile->ranges.size)
         {
           complaint (&symfile_complaints,
                      _("Offset %lu out of bounds for DW_AT_ranges attribute"),
@@ -5510,131 +5601,6 @@ read_die_and_siblings (gdb_byte *info_pt
     }
 }
 
-/* Decompress a section that was compressed using zlib.  Store the
-   decompressed buffer, and its size, in OUTBUF and OUTSIZE.  */
-
-static void
-zlib_decompress_section (struct objfile *objfile, asection *sectp,
-                         gdb_byte **outbuf, bfd_size_type *outsize)
-{
-  bfd *abfd = objfile->obfd;
-#ifndef HAVE_ZLIB_H
-  error (_("Support for zlib-compressed DWARF data (from '%s') "
-           "is disabled in this copy of GDB"),
-         bfd_get_filename (abfd));
-#else
-  bfd_size_type compressed_size = bfd_get_section_size (sectp);
-  gdb_byte *compressed_buffer = xmalloc (compressed_size);
-  bfd_size_type uncompressed_size;
-  gdb_byte *uncompressed_buffer;
-  z_stream strm;
-  int rc;
-  int header_size = 12;
-
-  if (bfd_seek (abfd, sectp->filepos, SEEK_SET) != 0
-      || bfd_bread (compressed_buffer, compressed_size, abfd) != compressed_size)
-    error (_("Dwarf Error: Can't read DWARF data from '%s'"),
-           bfd_get_filename (abfd));
-
-  /* Read the zlib header.  In this case, it should be "ZLIB" followed
-     by the uncompressed section size, 8 bytes in big-endian order.  */
-  if (compressed_size < header_size
-      || strncmp (compressed_buffer, "ZLIB", 4) != 0)
-    error (_("Dwarf Error: Corrupt DWARF ZLIB header from '%s'"),
-           bfd_get_filename (abfd));
-  uncompressed_size = compressed_buffer[4]; uncompressed_size <<= 8;
-  uncompressed_size += compressed_buffer[5]; uncompressed_size <<= 8;
-  uncompressed_size += compressed_buffer[6]; uncompressed_size <<= 8;
-  uncompressed_size += compressed_buffer[7]; uncompressed_size <<= 8;
-  uncompressed_size += compressed_buffer[8]; uncompressed_size <<= 8;
-  uncompressed_size += compressed_buffer[9]; uncompressed_size <<= 8;
-  uncompressed_size += compressed_buffer[10]; uncompressed_size <<= 8;
-  uncompressed_size += compressed_buffer[11];
-
-  /* It is possible the section consists of several compressed
-     buffers concatenated together, so we uncompress in a loop.  */
-  strm.zalloc = NULL;
-  strm.zfree = NULL;
-  strm.opaque = NULL;
-  strm.avail_in = compressed_size - header_size;
-  strm.next_in = (Bytef*) compressed_buffer + header_size;
-  strm.avail_out = uncompressed_size;
-  uncompressed_buffer = obstack_alloc (&objfile->objfile_obstack,
-                                       uncompressed_size);
-  rc = inflateInit (&strm);
-  while (strm.avail_in > 0)
-    {
-      if (rc != Z_OK)
-        error (_("Dwarf Error: setting up DWARF uncompression in '%s': %d"),
-               bfd_get_filename (abfd), rc);
-      strm.next_out = ((Bytef*) uncompressed_buffer
-                       + (uncompressed_size - strm.avail_out));
-      rc = inflate (&strm, Z_FINISH);
-      if (rc != Z_STREAM_END)
-        error (_("Dwarf Error: zlib error uncompressing from '%s': %d"),
-               bfd_get_filename (abfd), rc);
-      rc = inflateReset (&strm);
-    }
-  rc = inflateEnd (&strm);
-  if (rc != Z_OK
-      || strm.avail_out != 0)
-    error (_("Dwarf Error: concluding DWARF uncompression in '%s': %d"),
-           bfd_get_filename (abfd), rc);
-
-  xfree (compressed_buffer);
-  *outbuf = uncompressed_buffer;
-  *outsize = uncompressed_size;
-#endif
-}
-
-
-/* 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.
-   If the section is compressed, uncompress it before returning.  */
-
-gdb_byte *
-dwarf2_read_section (struct objfile *objfile, asection *sectp)
-{
-  bfd *abfd = objfile->obfd;
-  gdb_byte *buf, *retbuf;
-  bfd_size_type size = bfd_get_section_size (sectp);
-  unsigned char header[4];
-
-  if (size == 0)
-    return NULL;
-
-  /* Check if the file has a 4-byte header indicating compression.  */
-  if (size > sizeof (header)
-      && bfd_seek (abfd, sectp->filepos, SEEK_SET) == 0
-      && bfd_bread (header, sizeof (header), abfd) == sizeof (header))
-    {
-      /* Upon decompression, update the buffer and its size.  */
-      if (strncmp (header, "ZLIB", sizeof (header)) == 0)
-        {
-          zlib_decompress_section (objfile, sectp, &buf, &size);
-          dwarf2_resize_section (sectp, size);
-          return buf;
-        }
-    }
-
-  /* If we get here, we are a normal, not-compressed section.  */
-  buf = obstack_alloc (&objfile->objfile_obstack, size);
-  /* When debugging .o files, we may need to apply relocations; see
-     http://sourceware.org/ml/gdb-patches/2002-04/msg00136.html .
-     We never compress sections in .o files, so we only need to
-     try this when the section is not compressed.  */
-  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'"),
-	   bfd_get_filename (abfd));
-
-  return buf;
-}
-
 /* In DWARF version 2, the description of the debugging information is
    stored in a separate .debug_abbrev section.  Before we read any
    dies from a section we read in all abbreviations and install them
@@ -5660,7 +5626,7 @@ dwarf2_read_abbrevs (bfd *abfd, struct d
   memset (cu->dwarf2_abbrevs, 0,
           ABBREV_HASH_SIZE * sizeof (struct abbrev_info *));
 
-  abbrev_ptr = dwarf2_per_objfile->abbrev_buffer + cu_header->abbrev_offset;
+  abbrev_ptr = dwarf2_per_objfile->abbrev.buffer + cu_header->abbrev_offset;
   abbrev_number = read_unsigned_leb128 (abfd, abbrev_ptr, &bytes_read);
   abbrev_ptr += bytes_read;
 
@@ -5732,8 +5698,8 @@ dwarf2_read_abbrevs (bfd *abfd, struct d
          already read (which means we are about to read the abbreviations
          for the next compile unit) or if the end of the abbreviation
          table is reached.  */
-      if ((unsigned int) (abbrev_ptr - dwarf2_per_objfile->abbrev_buffer)
-	  >= dwarf2_per_objfile->abbrev_size)
+      if ((unsigned int) (abbrev_ptr - dwarf2_per_objfile->abbrev.buffer)
+	  >= dwarf2_per_objfile->abbrev.size)
 	break;
       abbrev_number = read_unsigned_leb128 (abfd, abbrev_ptr, &bytes_read);
       abbrev_ptr += bytes_read;
@@ -6051,7 +6017,7 @@ read_partial_die (struct partial_die_inf
 
   memset (part_die, 0, sizeof (struct partial_die_info));
 
-  part_die->offset = info_ptr - dwarf2_per_objfile->info_buffer;
+  part_die->offset = info_ptr - dwarf2_per_objfile->info.buffer;
 
   info_ptr += abbrev_len;
 
@@ -6164,7 +6130,7 @@ read_partial_die (struct partial_die_inf
 	  if (attr.form == DW_FORM_ref_addr)
 	    complaint (&symfile_complaints, _("ignoring absolute DW_AT_sibling"));
 	  else
-	    part_die->sibling = dwarf2_per_objfile->info_buffer
+	    part_die->sibling = dwarf2_per_objfile->info.buffer
 	      + dwarf2_get_ref_die_offset (&attr);
 	  break;
         case DW_AT_stmt_list:
@@ -6280,7 +6246,7 @@ find_partial_die (unsigned int offset, s
 	  dwarf2_read_abbrevs (per_cu->cu->objfile->obfd, per_cu->cu);
 	  back_to = make_cleanup (dwarf2_free_abbrev_table, per_cu->cu);
 	}
-      info_ptr = (dwarf2_per_objfile->info_buffer
+      info_ptr = (dwarf2_per_objfile->info.buffer
 		  + per_cu->cu->header.offset
 		  + per_cu->cu->header.first_die_offset);
       abbrev = peek_die_abbrev (info_ptr, &bytes_read, per_cu->cu);
@@ -6356,7 +6322,7 @@ read_full_die (struct die_info **diep, b
   struct abbrev_info *abbrev;
   struct die_info *die;
 
-  offset = info_ptr - dwarf2_per_objfile->info_buffer;
+  offset = info_ptr - dwarf2_per_objfile->info.buffer;
   abbrev_number = read_unsigned_leb128 (abfd, info_ptr, &bytes_read);
   info_ptr += bytes_read;
   if (!abbrev_number)
@@ -6792,22 +6758,22 @@ read_indirect_string (bfd *abfd, gdb_byt
 {
   LONGEST str_offset = read_offset (abfd, buf, cu_header, bytes_read_ptr);
 
-  if (dwarf2_per_objfile->str_buffer == NULL)
+  if (dwarf2_per_objfile->str.buffer == NULL)
     {
       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)
+  if (str_offset >= dwarf2_per_objfile->str.size)
     {
       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')
+  if (dwarf2_per_objfile->str.buffer[str_offset] == '\0')
     return NULL;
-  return (char *) (dwarf2_per_objfile->str_buffer + str_offset);
+  return (char *) (dwarf2_per_objfile->str.buffer + str_offset);
 }
 
 static unsigned long
@@ -7094,7 +7060,7 @@ dwarf_decode_line_header (unsigned int o
   int i;
   char *cur_dir, *cur_file;
 
-  if (dwarf2_per_objfile->line_buffer == NULL)
+  if (dwarf2_per_objfile->line.buffer == NULL)
     {
       complaint (&symfile_complaints, _("missing .debug_line section"));
       return 0;
@@ -7102,7 +7068,7 @@ dwarf_decode_line_header (unsigned int o
 
   /* 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)
+  if (offset + 4 >= dwarf2_per_objfile->line.size)
     {
       dwarf2_statement_list_fits_in_line_number_section_complaint ();
       return 0;
@@ -7113,15 +7079,15 @@ dwarf_decode_line_header (unsigned int o
   back_to = make_cleanup ((make_cleanup_ftype *) free_line_header,
                           (void *) lh);
 
-  line_ptr = dwarf2_per_objfile->line_buffer + offset;
+  line_ptr = dwarf2_per_objfile->line.buffer + offset;
 
   /* Read in the header.  */
   lh->total_length = 
     read_checked_initial_length_and_offset (abfd, line_ptr, &cu->header,
 					    &bytes_read, &offset_size);
   line_ptr += bytes_read;
-  if (line_ptr + lh->total_length > (dwarf2_per_objfile->line_buffer
-				     + dwarf2_per_objfile->line_size))
+  if (line_ptr + lh->total_length > (dwarf2_per_objfile->line.buffer
+				     + dwarf2_per_objfile->line.size))
     {
       dwarf2_statement_list_fits_in_line_number_section_complaint ();
       return 0;
@@ -7177,8 +7143,8 @@ dwarf_decode_line_header (unsigned int o
   line_ptr += bytes_read;
   lh->statement_program_start = line_ptr; 
 
-  if (line_ptr > (dwarf2_per_objfile->line_buffer
-		  + dwarf2_per_objfile->line_size))
+  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"));
 
@@ -10163,7 +10129,7 @@ dwarf_decode_macros (struct line_header 
   enum dwarf_macinfo_record_type macinfo_type;
   int at_commandline;
 
-  if (dwarf2_per_objfile->macinfo_buffer == NULL)
+  if (dwarf2_per_objfile->macinfo.buffer == NULL)
     {
       complaint (&symfile_complaints, _("missing .debug_macinfo section"));
       return;
@@ -10180,9 +10146,9 @@ dwarf_decode_macros (struct line_header 
      CURRENT_FILE accordingly so that any macro definition found before the
      first DW_MACINFO_start_file can still be associated to the base file.  */
 
-  mac_ptr = dwarf2_per_objfile->macinfo_buffer + offset;
-  mac_end = dwarf2_per_objfile->macinfo_buffer
-    + dwarf2_per_objfile->macinfo_size;
+  mac_ptr = dwarf2_per_objfile->macinfo.buffer + offset;
+  mac_end = dwarf2_per_objfile->macinfo.buffer
+    + dwarf2_per_objfile->macinfo.size;
 
   do
     {
@@ -10259,7 +10225,7 @@ dwarf_decode_macros (struct line_header 
      command-line macro definitions/undefinitions.  This flag is unset when we
      reach the first DW_MACINFO_start_file entry.  */
 
-  mac_ptr = dwarf2_per_objfile->macinfo_buffer + offset;
+  mac_ptr = dwarf2_per_objfile->macinfo.buffer + offset;
 
   /* Determines if GDB is still before first DW_MACINFO_start_file.  If true
      GDB is still reading the definitions from command line.  First
@@ -10477,7 +10443,7 @@ dwarf2_symbol_mark_computed (struct attr
       /* ".debug_loc" may not exist at all, or the offset may be outside
 	 the section.  If so, fall through to the complaint in the
 	 other branch.  */
-      && DW_UNSND (attr) < dwarf2_per_objfile->loc_size)
+      && DW_UNSND (attr) < dwarf2_per_objfile->loc.size)
     {
       struct dwarf2_loclist_baton *baton;
 
@@ -10488,8 +10454,8 @@ dwarf2_symbol_mark_computed (struct attr
 
       /* We don't know how long the location list is, but make sure we
 	 don't run off the edge of the section.  */
-      baton->size = dwarf2_per_objfile->loc_size - DW_UNSND (attr);
-      baton->data = dwarf2_per_objfile->loc_buffer + DW_UNSND (attr);
+      baton->size = dwarf2_per_objfile->loc.size - DW_UNSND (attr);
+      baton->data = dwarf2_per_objfile->loc.buffer + DW_UNSND (attr);
       baton->base_address = cu->base_address;
       if (cu->base_known == 0)
 	complaint (&symfile_complaints,
@@ -10558,7 +10524,7 @@ dwarf2_per_cu_addr_size (struct dwarf2_p
       struct objfile *objfile = per_cu->psymtab->objfile;
       struct dwarf2_per_objfile *per_objfile
 	= objfile_data (objfile, dwarf2_objfile_data_key);
-      gdb_byte *info_ptr = per_objfile->info_buffer + per_cu->offset;
+      gdb_byte *info_ptr = per_objfile->info.buffer + per_cu->offset;
 
       struct comp_unit_head cu_header;
       memset (&cu_header, 0, sizeof cu_header);
@@ -10951,12 +10917,49 @@ show_dwarf2_cmd (char *args, int from_tt
   cmd_show_list (show_dwarf2_cmdlist, from_tty, "");
 }
 
+/* If section described by INFO was mmapped, munmap it now.  */
+
+static void
+munmap_section_buffer (struct dwarf2_section_info *info)
+{
+  if (info->was_mmapped)
+    {
+#ifdef HAVE_MMAP
+      intptr_t begin = (intptr_t) info->buffer;
+      intptr_t map_begin = begin & ~(pagesize - 1);
+      size_t map_length = info->size + begin - map_begin;
+      gdb_assert (munmap ((void *) map_begin, map_length) == 0);
+#else
+      /* Without HAVE_MMAP, we should never be here to begin with.  */
+      gdb_assert (0);
+#endif
+    }
+}
+
+/* munmap debug sections for OBJFILE, if necessary.  */
+
+static void
+dwarf2_per_objfile_cleanup (struct objfile *objfile, void *d)
+{
+  struct dwarf2_per_objfile *data = d;
+  munmap_section_buffer (&data->info);
+  munmap_section_buffer (&data->abbrev);
+  munmap_section_buffer (&data->line);
+  munmap_section_buffer (&data->str);
+  munmap_section_buffer (&data->macinfo);
+  munmap_section_buffer (&data->ranges);
+  munmap_section_buffer (&data->loc);
+  munmap_section_buffer (&data->frame);
+  munmap_section_buffer (&data->eh_frame);
+}
+
 void _initialize_dwarf2_read (void);
 
 void
 _initialize_dwarf2_read (void)
 {
-  dwarf2_objfile_data_key = register_objfile_data ();
+  dwarf2_objfile_data_key
+    = register_objfile_data_with_cleanup (dwarf2_per_objfile_cleanup);
 
   add_prefix_cmd ("dwarf2", class_maintenance, set_dwarf2_cmd, _("\
 Set DWARF 2 specific variables.\n\
Index: dwarf2-frame.c
===================================================================
RCS file: /cvs/src/src/gdb/dwarf2-frame.c,v
retrieving revision 1.87
diff -u -p -u -r1.87 dwarf2-frame.c
--- dwarf2-frame.c	3 Jan 2009 05:57:51 -0000	1.87
+++ dwarf2-frame.c	16 Jun 2009 20:41:52 -0000
@@ -1896,15 +1896,9 @@ decode_frame_entry (struct comp_unit *un
 }
 \f
 
-/* FIXME: kettenis/20030504: This still needs to be integrated with
-   dwarf2read.c in a better way.  */
-
-/* Imported from dwarf2read.c.  */
-extern asection *dwarf_frame_section;
-extern asection *dwarf_eh_frame_section;
-
 /* Imported from dwarf2read.c.  */
-extern gdb_byte *dwarf2_read_section (struct objfile *objfile, asection *sectp);
+extern void dwarf2_get_section_info (struct objfile *, const char *, asection **,
+                                     gdb_byte **, bfd_size_type *);
 
 void
 dwarf2_build_frame_info (struct objfile *objfile)
@@ -1922,17 +1916,15 @@ dwarf2_build_frame_info (struct objfile 
 
   /* First add the information from the .eh_frame section.  That way,
      the FDEs from that section are searched last.  */
-  if (dwarf_eh_frame_section)
+  dwarf2_get_section_info (objfile, ".eh_frame",
+                           &unit->dwarf_frame_section,
+                           &unit->dwarf_frame_buffer,
+                           &unit->dwarf_frame_size);
+  if (unit->dwarf_frame_size)
     {
       asection *got, *txt;
 
       unit->cie = NULL;
-      unit->dwarf_frame_buffer = dwarf2_read_section (objfile,
-						      dwarf_eh_frame_section);
-
-      unit->dwarf_frame_size = bfd_get_section_size (dwarf_eh_frame_section);
-      unit->dwarf_frame_section = dwarf_eh_frame_section;
-
       /* FIXME: kettenis/20030602: This is the DW_EH_PE_datarel base
 	 that is used for the i386/amd64 target, which currently is
 	 the only target in GCC that supports/uses the
@@ -1952,13 +1944,13 @@ dwarf2_build_frame_info (struct objfile 
 	frame_ptr = decode_frame_entry (unit, frame_ptr, 1);
     }
 
-  if (dwarf_frame_section)
+  dwarf2_get_section_info (objfile, ".debug_frame",
+                           &unit->dwarf_frame_section,
+                           &unit->dwarf_frame_buffer,
+                           &unit->dwarf_frame_size);
+  if (unit->dwarf_frame_size)
     {
       unit->cie = NULL;
-      unit->dwarf_frame_buffer = dwarf2_read_section (objfile,
-						      dwarf_frame_section);
-      unit->dwarf_frame_size = bfd_get_section_size (dwarf_frame_section);
-      unit->dwarf_frame_section = dwarf_frame_section;
 
       frame_ptr = unit->dwarf_frame_buffer;
       while (frame_ptr < unit->dwarf_frame_buffer + unit->dwarf_frame_size)

  reply	other threads:[~2009-06-16 20:43 UTC|newest]

Thread overview: 29+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2009-05-27  0:12 Paul Pluzhnikov
2009-05-28  1:16 ` Tom Tromey
2009-05-28 16:57   ` Paul Pluzhnikov
2009-05-30 22:36     ` Tom Tromey
2009-06-11  1:40       ` Paul Pluzhnikov
2009-06-11  1:43         ` Paul Pluzhnikov
2009-06-16 19:19           ` Tom Tromey
2009-06-16 20:43             ` Paul Pluzhnikov [this message]
2009-06-16 20:59               ` Tom Tromey
2009-06-16 21:07                 ` Paul Pluzhnikov
2009-06-18  9:20                   ` Ken Werner
2009-06-18 14:06                     ` Paul Pluzhnikov
2009-06-18 14:11                       ` Paul Pluzhnikov
2009-06-18 15:02                       ` Ken Werner
2009-06-18 16:33                         ` Paul Pluzhnikov
2009-06-19  7:10                           ` Ken Werner
2009-06-23 15:03                   ` [patch] Fix a reread_symbols regression by mmap [Re: [patch] Use mmap instead of obstack_alloc for dwarf debug sections.] Jan Kratochvil
2009-06-23 17:35                     ` Paul Pluzhnikov
2009-06-23 18:08                     ` Tom Tromey
2009-06-23 18:21                       ` Jan Kratochvil
2009-06-23 20:00                         ` Tom Tromey
2009-06-25 19:21                           ` [patch] Replace reread_symbols by load+free calls Jan Kratochvil
2009-06-25 19:57                             ` Pedro Alves
2009-06-25 23:25                               ` Jan Kratochvil
2009-08-02 21:04                                 ` cancelled: " Jan Kratochvil
2009-08-14 23:09                             ` Tom Tromey
2009-08-14 23:12                               ` Pedro Alves
2009-08-17 15:41                                 ` Tom Tromey
2011-12-18 11:54                                 ` Jan Kratochvil

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=8ac60eac0906161342m67c30151lc7f685e0eb36e41f@mail.gmail.com \
    --to=ppluzhnikov@google.com \
    --cc=gdb-patches@sources.redhat.com \
    --cc=tromey@redhat.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox