PR 6832
[deliverable/binutils-gdb.git] / bfd / dwarf2.c
index a4918accc4596bd9abf92ee16ef2591d31d81e89..4f2e38c52846f5e35daa545120588a289e200394 100644 (file)
@@ -1,6 +1,6 @@
 /* DWARF 2 support.
    Copyright 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003,
-   2004, 2005, 2006, 2007, 2008 Free Software Foundation, Inc.
+   2004, 2005, 2006, 2007, 2008, 2009 Free Software Foundation, Inc.
 
    Adapted from gdb/dwarf2read.c by Gavin Koch of Cygnus Solutions
    (gavin@cygnus.com).
@@ -399,15 +399,19 @@ lookup_info_hash_table (struct info_hash_table *hash_table, const char *key)
 }
 
 /* Read a section into its appropriate place in the dwarf2_debug
-   struct (indicated by SECTION_BUFFER and SECTION_SIZE).  If syms is
+   struct (indicated by SECTION_BUFFER and SECTION_SIZE).  If SYMS is
    not NULL, use bfd_simple_get_relocated_section_contents to read the
-   section contents, otherwise use bfd_get_section_contents.  */
+   section contents, otherwise use bfd_get_section_contents.  Fail if
+   the located section does not contain at least OFFSET bytes.  */
 
 static bfd_boolean
-read_section (bfd *abfd,
-             const char* section_name, const char* compressed_section_name,
-             asymbol** syms, bfd_uint64_t offset,
-             bfd_byte **section_buffer, bfd_size_type *section_size)
+read_section (bfd *           abfd,
+             const char *    section_name,
+             const char *    compressed_section_name,
+             asymbol **      syms,
+             bfd_uint64_t    offset,
+             bfd_byte **     section_buffer,
+             bfd_size_type * section_size)
 {
   asection *msec;
   bfd_boolean section_is_compressed = FALSE;
@@ -459,11 +463,11 @@ read_section (bfd *abfd,
     }
 
   /* It is possible to get a bad value for the offset into the section
-   * that the client wants.  Validate it here to avoid trouble later.  */
+     that the client wants.  Validate it here to avoid trouble later.  */
   if (offset != 0 && offset >= *section_size)
     {
       (*_bfd_error_handler) (_("Dwarf Error: Offset (%lu) greater than or equal to %s size (%lu)."),
-                            offset, section_name, *section_size);
+                            (long) offset, section_name, *section_size);
       bfd_set_error (bfd_error_bad_value);
       return FALSE;
     }
@@ -512,9 +516,6 @@ read_n_bytes (bfd *abfd ATTRIBUTE_UNUSED,
              bfd_byte *buf,
              unsigned int size ATTRIBUTE_UNUSED)
 {
-  /* If the size of a host char is 8 bits, we can return a pointer
-     to the buffer, otherwise we have to copy the data to a buffer
-     allocated on the temporary obstack.  */
   return buf;
 }
 
@@ -525,6 +526,7 @@ read_string (bfd *abfd ATTRIBUTE_UNUSED,
 {
   /* Return a pointer to the embedded string.  */
   char *str = (char *) buf;
+
   if (*str == '\0')
     {
       *bytes_read_ptr = 1;
@@ -535,10 +537,12 @@ read_string (bfd *abfd ATTRIBUTE_UNUSED,
   return str;
 }
 
+/* END VERBATIM */
+
 static char *
-read_indirect_string (struct comp_unit* unit,
-                     bfd_byte *buf,
-                     unsigned int *bytes_read_ptr)
+read_indirect_string (struct comp_unit * unit,
+                     bfd_byte *         buf,
+                     unsigned int *     bytes_read_ptr)
 {
   bfd_uint64_t offset;
   struct dwarf2_debug *stash = unit->stash;
@@ -548,12 +552,13 @@ read_indirect_string (struct comp_unit* unit,
     offset = read_4_bytes (unit->abfd, buf);
   else
     offset = read_8_bytes (unit->abfd, buf);
+
   *bytes_read_ptr = unit->offset_size;
 
   if (! read_section (unit->abfd, ".debug_str", ".zdebug_str",
-                     0, offset,
+                     stash->syms, offset,
                      &stash->dwarf_str_buffer, &stash->dwarf_str_size))
-    return 0;
+    return NULL;
 
   str = (char *) stash->dwarf_str_buffer + offset;
   if (*str == '\0')
@@ -561,8 +566,6 @@ read_indirect_string (struct comp_unit* unit,
   return str;
 }
 
-/* END VERBATIM */
-
 static bfd_uint64_t
 read_address (struct comp_unit *unit, bfd_byte *buf)
 {
@@ -2989,8 +2992,6 @@ find_line (bfd *abfd,
                              symbols, 0,
                              &stash->info_ptr_memory, &total_size))
            goto done;
-         stash->info_ptr = stash->info_ptr_memory;
-         stash->info_ptr_end = stash->info_ptr + total_size;
        }
       else
        {
@@ -3008,63 +3009,64 @@ find_line (bfd *abfd,
              if (stash->info_ptr_memory == NULL)
                goto done;
 
-             stash->info_ptr = stash->info_ptr_memory;
-             stash->info_ptr_end = stash->info_ptr;
-
+             total_size = 0;
              for (msec = find_debug_info (debug_bfd, NULL);
                   msec;
                   msec = find_debug_info (debug_bfd, msec))
                {
                  bfd_size_type size;
-                 bfd_size_type start;
 
                  size = msec->size;
                  if (size == 0)
                    continue;
 
-                 start = stash->info_ptr_end - stash->info_ptr;
-
-                 if ((bfd_simple_get_relocated_section_contents
-                      (debug_bfd, msec, stash->info_ptr + start, symbols))
-                     == NULL)
-                   continue;
+                 if (!(bfd_simple_get_relocated_section_contents
+                       (debug_bfd, msec, stash->info_ptr_memory + total_size,
+                        symbols)))
+                   goto done;
 
-                 stash->info_ptr_end = stash->info_ptr + start + size;
+                 total_size += size;
                }
-
-             BFD_ASSERT (stash->info_ptr_end == stash->info_ptr + total_size);
            }
          else
            {
              /* Case 3: multiple sections, some or all compressed.  */
-             stash->info_ptr_memory = bfd_malloc (1);
-             stash->info_ptr = stash->info_ptr_memory;
-             stash->info_ptr_end = stash->info_ptr;
+             stash->info_ptr_memory = NULL;
+             total_size = 0;
              for (msec = find_debug_info (debug_bfd, NULL);
                   msec;
                   msec = find_debug_info (debug_bfd, msec))
                {
                  bfd_size_type size = msec->size;
-                 bfd_byte* buffer
-                     = (bfd_simple_get_relocated_section_contents
-                        (debug_bfd, msec, NULL, symbols));
-                 if (! buffer)
+                 bfd_byte* buffer;
+
+                 if (size == 0)
                    continue;
+
+                 buffer = (bfd_simple_get_relocated_section_contents
+                           (debug_bfd, msec, NULL, symbols));
+                 if (! buffer)
+                   goto done;
+
                  if (strcmp (msec->name, DWARF2_COMPRESSED_DEBUG_INFO) == 0)
                    {
                      if (! bfd_uncompress_section_contents (&buffer, &size))
-                       continue;
+                       {
+                         free (buffer);
+                         goto done;
+                       }
                    }
-                 stash->info_ptr = bfd_realloc (stash->info_ptr,
-                                                stash->info_ptr_end
-                                                - stash->info_ptr + size);
-                 memcpy (stash->info_ptr_end, buffer, size);
+                 stash->info_ptr_memory = bfd_realloc (stash->info_ptr_memory,
+                                                       total_size + size);
+                 memcpy (stash->info_ptr_memory + total_size, buffer, size);
                  free (buffer);
-                 stash->info_ptr_end += size;
+                 total_size += size;
                }
            }
        }
 
+      stash->info_ptr = stash->info_ptr_memory;
+      stash->info_ptr_end = stash->info_ptr + total_size;
       stash->sec = find_debug_info (debug_bfd, NULL);
       stash->sec_info_ptr = stash->info_ptr;
       stash->syms = symbols;
@@ -3187,13 +3189,6 @@ find_line (bfd *abfd,
            break;
          stash->info_ptr += length;
 
-         if ((bfd_vma) (stash->info_ptr - stash->sec_info_ptr)
-             == stash->sec->size)
-           {
-             stash->sec = find_debug_info (stash->bfd, stash->sec);
-             stash->sec_info_ptr = stash->info_ptr;
-           }
-
          if (stash->all_comp_units)
            stash->all_comp_units->prev_unit = each;
          else
@@ -3223,6 +3218,14 @@ find_line (bfd *abfd,
                                                     functionname_ptr,
                                                     linenumber_ptr,
                                                     stash));
+
+         if ((bfd_vma) (stash->info_ptr - stash->sec_info_ptr)
+             == stash->sec->size)
+           {
+             stash->sec = find_debug_info (stash->bfd, stash->sec);
+             stash->sec_info_ptr = stash->info_ptr;
+           }
+
          if (found)
            goto done;
        }
@@ -3364,8 +3367,14 @@ _bfd_dwarf2_cleanup_debug_info (bfd *abfd)
        }
     }
 
-  free (stash->dwarf_abbrev_buffer);
-  free (stash->dwarf_line_buffer);
-  free (stash->dwarf_ranges_buffer);
-  free (stash->info_ptr_memory);
+  if (stash->dwarf_abbrev_buffer)
+    free (stash->dwarf_abbrev_buffer);
+  if (stash->dwarf_line_buffer)
+    free (stash->dwarf_line_buffer);
+  if (stash->dwarf_str_buffer)
+    free (stash->dwarf_str_buffer);
+  if (stash->dwarf_ranges_buffer)
+    free (stash->dwarf_ranges_buffer);
+  if (stash->info_ptr_memory)
+    free (stash->info_ptr_memory);
 }
This page took 0.032552 seconds and 4 git commands to generate.