* dwarf2.c (find_line): New. Contains the duplicated code from:
authorNick Clifton <nickc@redhat.com>
Tue, 26 Jun 2007 14:28:13 +0000 (14:28 +0000)
committerNick Clifton <nickc@redhat.com>
Tue, 26 Jun 2007 14:28:13 +0000 (14:28 +0000)
  (_bfd_dwarf2_find_nearest_line): Use it.
  (_bfd_dwarf2_find_line): Use it.

bfd/ChangeLog
bfd/dwarf2.c

index a18f205bb9b42a4f1e03d987bacb4f8100ef46f2..fcad64682998025b6e29cacbedb211c55ee87589 100644 (file)
@@ -1,3 +1,9 @@
+2007-06-26  H.J. Lu  <hongjiu.lu@intel.com>
+
+       * dwarf2.c (find_line): New.  Contains the duplicated code from:
+       (_bfd_dwarf2_find_nearest_line): Use it.
+       (_bfd_dwarf2_find_line): Use it.
+
 2007-06-26  Joseph Myers  <joseph@codesourcery.com>
 
        * elf32-arm.c (copy_eabi_attributes): Copy type of attributes.
index 2ba3152d5215d3874607bfcc5aeafdae04c67c58..411a7154b5eb37232cefe7d26fd52171e9bb3925 100644 (file)
@@ -2301,22 +2301,28 @@ place_sections (bfd *abfd, struct dwarf2_debug *stash)
   return TRUE;
 }
 
-/* The DWARF2 version of find_nearest_line.  Return TRUE if the line
-   is found without error.  ADDR_SIZE is the number of bytes in the
-   initial .debug_info length field and in the abbreviation offset.
-   You may use zero to indicate that the default value should be
-   used.  */
+/* Find the source code location of SYMBOL.  If SYMBOL is NULL
+   then find the nearest source code location corresponding to
+   the address SECTION + OFFSET.
+   Returns TRUE if the line is found without error and fills in
+   FILENAME_PTR and LINENUMBER_PTR.  In the case where SYMBOL was
+   NULL the FUNCTIONNAME_PTR is also filled in.
+   SYMBOLS contains the symbol table for ABFD.
+   ADDR_SIZE is the number of bytes in the initial .debug_info length
+   field and in the abbreviation offset, or zero to indicate that the
+   default value should be used.  */
 
-bfd_boolean
-_bfd_dwarf2_find_nearest_line (bfd *abfd,
-                              asection *section,
-                              asymbol **symbols,
-                              bfd_vma offset,
-                              const char **filename_ptr,
-                              const char **functionname_ptr,
-                              unsigned int *linenumber_ptr,
-                              unsigned int addr_size,
-                              void **pinfo)
+static bfd_boolean
+find_line (bfd *abfd,
+          asection *section,
+          bfd_vma offset,
+          asymbol *symbol,
+          asymbol **symbols,
+          const char **filename_ptr,
+          const char **functionname_ptr,
+          unsigned int *linenumber_ptr,
+          unsigned int addr_size,
+          void **pinfo)
 {
   /* Read each compilation unit from the section .debug_info, and check
      to see if it contains the address we are searching for.  If yes,
@@ -2331,6 +2337,7 @@ _bfd_dwarf2_find_nearest_line (bfd *abfd,
   bfd_vma addr;
   struct comp_unit* each;
   bfd_vma found = FALSE;
+  bfd_boolean do_line;
 
   stash = *pinfo;
 
@@ -2351,7 +2358,22 @@ _bfd_dwarf2_find_nearest_line (bfd *abfd,
        return FALSE;
     }
 
-  addr = offset;
+  do_line = (section == NULL
+            && offset == 0
+            && functionname_ptr == NULL
+            && symbol != NULL);
+  if (do_line)
+    {
+      addr = symbol->value;
+      section = bfd_get_section (symbol);
+    }
+  else if (section != NULL
+          && functionname_ptr != NULL
+          && symbol == NULL)
+    addr = offset;
+  else
+    abort ();
+
   if (section->output_section)
     addr += section->output_section->vma + section->output_offset;
   else
@@ -2360,13 +2382,6 @@ _bfd_dwarf2_find_nearest_line (bfd *abfd,
   *functionname_ptr = NULL;
   *linenumber_ptr = 0;
 
-  /* The DWARF2 spec says that the initial length field, and the
-     offset of the abbreviation table, should both be 4-byte values.
-     However, some compilers do things differently.  */
-  if (addr_size == 0)
-    addr_size = 4;
-  BFD_ASSERT (addr_size == 4 || addr_size == 8);
-
   if (! *pinfo)
     {
       bfd *debug_bfd;
@@ -2452,254 +2467,24 @@ _bfd_dwarf2_find_nearest_line (bfd *abfd,
 
   /* Check the previously read comp. units first.  */
   for (each = stash->all_comp_units; each; each = each->next_unit)
-    if (comp_unit_contains_address (each, addr)
-       && comp_unit_find_nearest_line (each, addr, filename_ptr,
-                                       functionname_ptr,
-                                       linenumber_ptr, stash))
-      {
-       found = TRUE;
-       goto done;
-      }
-
-  /* Read each remaining comp. units checking each as they are read.  */
-  while (stash->info_ptr < stash->info_ptr_end)
-    {
-      bfd_vma length;
-      unsigned int offset_size = addr_size;
-      bfd_byte *info_ptr_unit = stash->info_ptr;
-
-      length = read_4_bytes (stash->bfd, stash->info_ptr);
-      /* A 0xffffff length is the DWARF3 way of indicating we use
-        64-bit offsets, instead of 32-bit offsets.  */
-      if (length == 0xffffffff)
-       {
-         offset_size = 8;
-         length = read_8_bytes (stash->bfd, stash->info_ptr + 4);
-         stash->info_ptr += 12;
-       }
-      /* A zero length is the IRIX way of indicating 64-bit offsets,
-        mostly because the 64-bit length will generally fit in 32
-        bits, and the endianness helps.  */
-      else if (length == 0)
-       {
-         offset_size = 8;
-         length = read_4_bytes (stash->bfd, stash->info_ptr + 4);
-         stash->info_ptr += 8;
-       }
-      /* In the absence of the hints above, we assume 32-bit DWARF2
-        offsets even for targets with 64-bit addresses, because:
-          a) most of the time these targets will not have generated
-             more than 2Gb of debug info and so will not need 64-bit
-             offsets,
-        and
-          b) if they do use 64-bit offsets but they are not using
-             the size hints that are tested for above then they are
-             not conforming to the DWARF3 standard anyway.  */
-      else if (addr_size == 8)
-       {
-         offset_size = 4;
-          stash->info_ptr += 4;
-       }
-      else
-       stash->info_ptr += 4;
-
-      if (length > 0)
-       {
-         each = parse_comp_unit (stash, length, info_ptr_unit,
-                                 offset_size);
-         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 (each)
-           {
-             each->next_unit = stash->all_comp_units;
-             stash->all_comp_units = each;
-
-             /* DW_AT_low_pc and DW_AT_high_pc are optional for
-                compilation units.  If we don't have them (i.e.,
-                unit->high == 0), we need to consult the line info
-                table to see if a compilation unit contains the given
-                address.  */
-             if ((each->arange.high == 0
-                  || comp_unit_contains_address (each, addr))
-                 && comp_unit_find_nearest_line (each, addr,
-                                                 filename_ptr,
-                                                 functionname_ptr,
-                                                 linenumber_ptr,
-                                                 stash))
-               {
-                 found = TRUE;
-                 goto done;
-               }
-           }
-       }
-    }
-
-done:
-  if ((abfd->flags & (EXEC_P | DYNAMIC)) == 0)
-    unset_sections (stash);
-
-  return found;
-}
-
-/* The DWARF2 version of find_line.  Return TRUE if the line is found
-   without error.  */
-
-bfd_boolean
-_bfd_dwarf2_find_line (bfd *abfd,
-                      asymbol **symbols,
-                      asymbol *symbol,
-                      const char **filename_ptr,
-                      unsigned int *linenumber_ptr,
-                      unsigned int addr_size,
-                      void **pinfo)
-{
-  /* Read each compilation unit from the section .debug_info, and check
-     to see if it contains the address we are searching for.  If yes,
-     lookup the address, and return the line number info.  If no, go
-     on to the next compilation unit.
-
-     We keep a list of all the previously read compilation units, and
-     a pointer to the next un-read compilation unit.  Check the
-     previously read units before reading more.  */
-  struct dwarf2_debug *stash;
-  /* What address are we looking for?  */
-  bfd_vma addr;
-  struct comp_unit* each;
-  asection *section;
-  bfd_boolean found = FALSE;
-
-  section = bfd_get_section (symbol);
-
-  stash = *pinfo;
-
-  if (! stash)
-    {
-      bfd_size_type amt = sizeof (struct dwarf2_debug);
-
-      stash = bfd_zalloc (abfd, amt);
-      if (! stash)
-       return FALSE;
-    }
-
-  /* In a relocatable file, 2 functions may have the same address.
-     We change the section vma so that they won't overlap.  */
-  if (!stash && (abfd->flags & (EXEC_P | DYNAMIC)) == 0)
     {
-      if (! place_sections (abfd, stash))
-       return FALSE;
-    }
-
-  addr = symbol->value;
-  if (section->output_section)
-    addr += section->output_section->vma + section->output_offset;
-  else
-    addr += section->vma;
-
-  *filename_ptr = NULL;
-  *filename_ptr = NULL;
-  *linenumber_ptr = 0;
-
-  if (! *pinfo)
-    {
-      bfd *debug_bfd;
-      bfd_size_type total_size;
-      asection *msec;
-
-      *pinfo = stash;
-
-      msec = find_debug_info (abfd, NULL);
-      if (msec == NULL)
-       {
-         char * debug_filename = bfd_follow_gnu_debuglink (abfd, DEBUGDIR);
-
-         if (debug_filename == NULL)
-           /* No dwarf2 info, and no gnu_debuglink to follow.
-              Note that at this point the stash has been allocated, but
-              contains zeros.  This lets future calls to this function
-              fail more quickly.  */
-           goto done;
-
-         if ((debug_bfd = bfd_openr (debug_filename, NULL)) == NULL
-             || ! bfd_check_format (debug_bfd, bfd_object)
-             || (msec = find_debug_info (debug_bfd, NULL)) == NULL)
-           {
-             if (debug_bfd)
-               bfd_close (debug_bfd);
-             /* FIXME: Should we report our failure to follow the debuglink ?  */
-             free (debug_filename);
-             goto done;
-           }
-       }
+      if (do_line)
+       found = (((symbol->flags & BSF_FUNCTION) == 0
+                 || comp_unit_contains_address (each, addr))
+                && comp_unit_find_line (each, symbol, addr,
+                                        filename_ptr, linenumber_ptr,
+                                        stash));
       else
-       debug_bfd = abfd;
-
-      /* There can be more than one DWARF2 info section in a BFD these days.
-        Read them all in and produce one large stash.  We do this in two
-        passes - in the first pass we just accumulate the section sizes.
-        In the second pass we read in the section's contents.  The allows
-        us to avoid reallocing the data as we add sections to the stash.  */
-      for (total_size = 0; msec; msec = find_debug_info (debug_bfd, msec))
-       total_size += msec->size;
-
-      stash->info_ptr = bfd_alloc (debug_bfd, total_size);
-      if (stash->info_ptr == NULL)
+       found = (comp_unit_contains_address (each, addr)
+                && comp_unit_find_nearest_line (each, addr,
+                                                filename_ptr,
+                                                functionname_ptr,
+                                                linenumber_ptr,
+                                                stash));
+      if (found)
        goto done;
-
-      stash->info_ptr_end = stash->info_ptr;
-
-      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;
-
-         stash->info_ptr_end = stash->info_ptr + start + size;
-       }
-
-      BFD_ASSERT (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;
-      stash->bfd = debug_bfd;
     }
 
-  /* A null info_ptr indicates that there is no dwarf2 info
-     (or that an error occured while setting up the stash).  */
-  if (! stash->info_ptr)
-    goto done;
-
-  stash->inliner_chain = NULL;
-
-  /* Check the previously read comp. units first.  */
-  for (each = stash->all_comp_units; each; each = each->next_unit)
-    if ((symbol->flags & BSF_FUNCTION) == 0
-       || comp_unit_contains_address (each, addr))
-      {
-       found = comp_unit_find_line (each, symbol, addr, filename_ptr,
-                                    linenumber_ptr, stash);
-       if (found)
-         goto done;
-      }
-
   /* The DWARF2 spec says that the initial length field, and the
      offset of the abbreviation table, should both be 4-byte values.
      However, some compilers do things differently.  */
@@ -2715,8 +2500,8 @@ _bfd_dwarf2_find_line (bfd *abfd,
       bfd_byte *info_ptr_unit = stash->info_ptr;
 
       length = read_4_bytes (stash->bfd, stash->info_ptr);
-      /* A 0xffffff length is the DWARF3 way of indicating we use
-        64-bit offsets, instead of 32-bit offsets.  */
+      /* A 0xffffff length is the DWARF3 way of indicating
+        we use 64-bit offsets, instead of 32-bit offsets.  */
       if (length == 0xffffffff)
        {
          offset_size = 8;
@@ -2772,13 +2557,22 @@ _bfd_dwarf2_find_line (bfd *abfd,
                 unit->high == 0), we need to consult the line info
                 table to see if a compilation unit contains the given
                 address.  */
-             found = (((symbol->flags & BSF_FUNCTION) == 0
-                       || each->arange.high <= 0
-                       || comp_unit_contains_address (each, addr))
-                      && comp_unit_find_line (each, symbol, addr,
-                                              filename_ptr,
-                                              linenumber_ptr,
-                                              stash));
+             if (do_line)
+               found = (((symbol->flags & BSF_FUNCTION) == 0
+                         || each->arange.high == 0
+                         || comp_unit_contains_address (each, addr))
+                        && comp_unit_find_line (each, symbol, addr,
+                                                filename_ptr,
+                                                linenumber_ptr,
+                                                stash));
+             else
+               found = ((each->arange.high == 0
+                         || comp_unit_contains_address (each, addr))
+                        && comp_unit_find_nearest_line (each, addr,
+                                                        filename_ptr,
+                                                        functionname_ptr,
+                                                        linenumber_ptr,
+                                                        stash));
              if (found)
                goto done;
            }
@@ -2792,6 +2586,42 @@ done:
   return found;
 }
 
+/* The DWARF2 version of find_nearest_line.
+   Return TRUE if the line is found without error.  */
+
+bfd_boolean
+_bfd_dwarf2_find_nearest_line (bfd *abfd,
+                              asection *section,
+                              asymbol **symbols,
+                              bfd_vma offset,
+                              const char **filename_ptr,
+                              const char **functionname_ptr,
+                              unsigned int *linenumber_ptr,
+                              unsigned int addr_size,
+                              void **pinfo)
+{
+  return find_line (abfd, section, offset, NULL, symbols, filename_ptr,
+                   functionname_ptr, linenumber_ptr, addr_size,
+                   pinfo);
+}
+
+/* The DWARF2 version of find_line.
+   Return TRUE if the line is found without error.  */
+
+bfd_boolean
+_bfd_dwarf2_find_line (bfd *abfd,
+                      asymbol **symbols,
+                      asymbol *symbol,
+                      const char **filename_ptr,
+                      unsigned int *linenumber_ptr,
+                      unsigned int addr_size,
+                      void **pinfo)
+{
+  return find_line (abfd, NULL, 0, symbol, symbols, filename_ptr,
+                   NULL, linenumber_ptr, addr_size,
+                   pinfo);
+}
+
 bfd_boolean
 _bfd_dwarf2_find_inliner_info (bfd *abfd ATTRIBUTE_UNUSED,
                               const char **filename_ptr,
@@ -2805,17 +2635,18 @@ _bfd_dwarf2_find_inliner_info (bfd *abfd ATTRIBUTE_UNUSED,
   if (stash)
     {
       struct funcinfo *func = stash->inliner_chain;
+
       if (func && func->caller_func)
        {
          *filename_ptr = func->caller_file;
          *functionname_ptr = func->caller_func->name;
          *linenumber_ptr = func->caller_line;
          stash->inliner_chain = func->caller_func;
-         return (TRUE);
+         return TRUE;
        }
     }
 
-  return (FALSE);
+  return FALSE;
 }
 
 void