| Line 3115... | Line 3115... | 
      
        |                                       filename_ptr, linenumber_ptr);
 |                                       filename_ptr, linenumber_ptr);
 | 
      
        |   return info_hash_lookup_varinfo (stash->varinfo_hash_table, sym, addr,
 |   return info_hash_lookup_varinfo (stash->varinfo_hash_table, sym, addr,
 | 
      
        |                                    filename_ptr, linenumber_ptr);
 |                                    filename_ptr, linenumber_ptr);
 | 
      
        | }
 | }
 | 
      
        |  
 |  
 | 
      
        | /* Find the source code location of SYMBOL.  If SYMBOL is NULL
 | /* Read debug information from DEBUG_BFD when DEBUG_BFD is specified.
 | 
      
        |    then find the nearest source code location corresponding to
 |    If DEBUG_BFD is not specified, we read debug information from ABFD
 | 
      
        |    the address SECTION + OFFSET.
 |    or its gnu_debuglink. The results will be stored in PINFO.
 | 
      
        |    Returns TRUE if the line is found without error and fills in
 |    The function returns TRUE iff debug information is ready.  */
 | 
      
        |    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.
 |   | 
      
        |    DEBUG_SECTIONS contains the name of the dwarf debug sections.
 |   | 
      
        |    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.  */
 |   | 
      
        |  
 |  
 | 
      
        | static bfd_boolean
 | bfd_boolean
 | 
      
        | find_line (bfd *abfd,
 | _bfd_dwarf2_slurp_debug_info (bfd *abfd, bfd *debug_bfd,
 | 
      
        |            const struct dwarf_debug_section *debug_sections,
 |            const struct dwarf_debug_section *debug_sections,
 | 
      
        |            asection *section,
 |   | 
      
        |            bfd_vma offset,
 |   | 
      
        |            asymbol *symbol,
 |   | 
      
        |            asymbol **symbols,
 |            asymbol **symbols,
 | 
      
        |            const char **filename_ptr,
 |   | 
      
        |            const char **functionname_ptr,
 |   | 
      
        |            unsigned int *linenumber_ptr,
 |   | 
      
        |            unsigned int addr_size,
 |   | 
      
        |            void **pinfo)
 |            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;
 |   | 
      
        |   bfd_vma found = FALSE;
 |   | 
      
        |   bfd_boolean do_line;
 |   | 
      
        |  
 |   | 
      
        |   stash = (struct dwarf2_debug *) *pinfo;
 |   | 
      
        |  
 |   | 
      
        |   if (! stash)
 |   | 
      
        |     {
 |   | 
      
        |       bfd_size_type amt = sizeof (struct dwarf2_debug);
 |       bfd_size_type amt = sizeof (struct dwarf2_debug);
 | 
      
        |   |   bfd_size_type total_size;
 | 
      
        |   |   asection *msec;
 | 
      
        |   |   struct dwarf2_debug *stash = (struct dwarf2_debug *) *pinfo;
 | 
      
        |   |  
 | 
      
        |   |   if (stash != NULL)
 | 
      
        |   |     return TRUE;
 | 
      
        |  
 |  
 | 
      
        |       stash = (struct dwarf2_debug *) bfd_zalloc (abfd, amt);
 |       stash = (struct dwarf2_debug *) bfd_zalloc (abfd, amt);
 | 
      
        |       if (! stash)
 |       if (! stash)
 | 
      
        |         return FALSE;
 |         return FALSE;
 | 
      
        |       stash->debug_sections = debug_sections;
 |       stash->debug_sections = debug_sections;
 | 
      
        |     }
 |   | 
      
        |  
 |   | 
      
        |   /* In a relocatable file, 2 functions may have the same address.
 |   | 
      
        |      We change the section vma so that they won't overlap.  */
 |   | 
      
        |   if ((abfd->flags & (EXEC_P | DYNAMIC)) == 0)
 |   | 
      
        |     {
 |   | 
      
        |       if (! place_sections (abfd, stash))
 |   | 
      
        |         return FALSE;
 |   | 
      
        |     }
 |   | 
      
        |  
 |   | 
      
        |   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
 |   | 
      
        |     addr += section->vma;
 |   | 
      
        |   *filename_ptr = NULL;
 |   | 
      
        |   if (! do_line)
 |   | 
      
        |     *functionname_ptr = NULL;
 |   | 
      
        |   *linenumber_ptr = 0;
 |   | 
      
        |  
 |   | 
      
        |   if (! *pinfo)
 |   | 
      
        |     {
 |   | 
      
        |       bfd *debug_bfd;
 |   | 
      
        |       bfd_size_type total_size;
 |   | 
      
        |       asection *msec;
 |   | 
      
        |  
 |  
 | 
      
        |       *pinfo = stash;
 |       *pinfo = stash;
 | 
      
        |  
 |  
 | 
      
        |       msec = find_debug_info (abfd, debug_sections, NULL);
 |   if (debug_bfd == NULL)
 | 
      
        |       if (msec == NULL)
 |     debug_bfd = abfd;
 | 
      
        |   |  
 | 
      
        |   |   msec = find_debug_info (debug_bfd, debug_sections, NULL);
 | 
      
        |   |   if (msec == NULL && abfd == debug_bfd)
 | 
      
        |         {
 |         {
 | 
      
        |           char * debug_filename = bfd_follow_gnu_debuglink (abfd, DEBUGDIR);
 |           char * debug_filename = bfd_follow_gnu_debuglink (abfd, DEBUGDIR);
 | 
      
        |  
 |  
 | 
      
        |           if (debug_filename == NULL)
 |           if (debug_filename == NULL)
 | 
      
        |             /* No dwarf2 info, and no gnu_debuglink to follow.
 |             /* No dwarf2 info, and no gnu_debuglink to follow.
 | 
      
        |                Note that at this point the stash has been allocated, but
 |                Note that at this point the stash has been allocated, but
 | 
      
        |                contains zeros.  This lets future calls to this function
 |                contains zeros.  This lets future calls to this function
 | 
      
        |                fail more quickly.  */
 |                fail more quickly.  */
 | 
      
        |             goto done;
 |         return FALSE;
 | 
      
        |  
 |  
 | 
      
        |           if ((debug_bfd = bfd_openr (debug_filename, NULL)) == NULL
 |           if ((debug_bfd = bfd_openr (debug_filename, NULL)) == NULL
 | 
      
        |               || ! bfd_check_format (debug_bfd, bfd_object)
 |               || ! bfd_check_format (debug_bfd, bfd_object)
 | 
      
        |               || (msec = find_debug_info (debug_bfd,
 |               || (msec = find_debug_info (debug_bfd,
 | 
      
        |                                           debug_sections, NULL)) == NULL)
 |                                           debug_sections, NULL)) == NULL)
 | 
      
        |             {
 |             {
 | 
      
        |               if (debug_bfd)
 |               if (debug_bfd)
 | 
      
        |                 bfd_close (debug_bfd);
 |                 bfd_close (debug_bfd);
 | 
      
        |               /* FIXME: Should we report our failure to follow the debuglink ?  */
 |               /* FIXME: Should we report our failure to follow the debuglink ?  */
 | 
      
        |               free (debug_filename);
 |               free (debug_filename);
 | 
      
        |               goto done;
 |           return FALSE;
 | 
      
        |             }
 |             }
 | 
      
        |         }
 |         }
 | 
      
        |       else
 |   | 
      
        |         debug_bfd = abfd;
 |   | 
      
        |  
 |  
 | 
      
        |       /* There can be more than one DWARF2 info section in a BFD these
 |       /* There can be more than one DWARF2 info section in a BFD these
 | 
      
        |          days.  First handle the easy case when there's only one.  If
 |          days.  First handle the easy case when there's only one.  If
 | 
      
        |          there's more than one, try case two: none of the sections is
 |          there's more than one, try case two: none of the sections is
 | 
      
        |          compressed.  In that case, read them all in and produce one
 |          compressed.  In that case, read them all in and produce one
 | 
      
        | Line 3253... | Line 3187... | 
      
        |           /* Case 1: only one info section.  */
 |           /* Case 1: only one info section.  */
 | 
      
        |           total_size = msec->size;
 |           total_size = msec->size;
 | 
      
        |           if (! read_section (debug_bfd, &stash->debug_sections[debug_info],
 |           if (! read_section (debug_bfd, &stash->debug_sections[debug_info],
 | 
      
        |                               symbols, 0,
 |                               symbols, 0,
 | 
      
        |                               &stash->info_ptr_memory, &total_size))
 |                               &stash->info_ptr_memory, &total_size))
 | 
      
        |             goto done;
 |         return FALSE;
 | 
      
        |         }
 |         }
 | 
      
        |       else
 |       else
 | 
      
        |         {
 |         {
 | 
      
        |           /* Case 2: multiple sections.  */
 |           /* Case 2: multiple sections.  */
 | 
      
        |           for (total_size = 0;
 |           for (total_size = 0;
 | 
      
        | Line 3265... | Line 3199... | 
      
        |                msec = find_debug_info (debug_bfd, debug_sections, msec))
 |                msec = find_debug_info (debug_bfd, debug_sections, msec))
 | 
      
        |             total_size += msec->size;
 |             total_size += msec->size;
 | 
      
        |  
 |  
 | 
      
        |           stash->info_ptr_memory = (bfd_byte *) bfd_malloc (total_size);
 |           stash->info_ptr_memory = (bfd_byte *) bfd_malloc (total_size);
 | 
      
        |           if (stash->info_ptr_memory == NULL)
 |           if (stash->info_ptr_memory == NULL)
 | 
      
        |             goto done;
 |         return FALSE;
 | 
      
        |  
 |  
 | 
      
        |           total_size = 0;
 |           total_size = 0;
 | 
      
        |           for (msec = find_debug_info (debug_bfd, debug_sections, NULL);
 |           for (msec = find_debug_info (debug_bfd, debug_sections, NULL);
 | 
      
        |                msec;
 |                msec;
 | 
      
        |                msec = find_debug_info (debug_bfd, debug_sections, msec))
 |                msec = find_debug_info (debug_bfd, debug_sections, msec))
 | 
      
        | Line 3281... | Line 3215... | 
      
        |                 continue;
 |                 continue;
 | 
      
        |  
 |  
 | 
      
        |               if (!(bfd_simple_get_relocated_section_contents
 |               if (!(bfd_simple_get_relocated_section_contents
 | 
      
        |                     (debug_bfd, msec, stash->info_ptr_memory + total_size,
 |                     (debug_bfd, msec, stash->info_ptr_memory + total_size,
 | 
      
        |                      symbols)))
 |                      symbols)))
 | 
      
        |                 goto done;
 |             return FALSE;
 | 
      
        |  
 |  
 | 
      
        |               total_size += size;
 |               total_size += size;
 | 
      
        |             }
 |             }
 | 
      
        |         }
 |         }
 | 
      
        |  
 |  
 | 
      
        | Line 3293... | Line 3227... | 
      
        |       stash->info_ptr_end = stash->info_ptr + total_size;
 |       stash->info_ptr_end = stash->info_ptr + total_size;
 | 
      
        |       stash->sec = find_debug_info (debug_bfd, debug_sections, NULL);
 |       stash->sec = find_debug_info (debug_bfd, debug_sections, NULL);
 | 
      
        |       stash->sec_info_ptr = stash->info_ptr;
 |       stash->sec_info_ptr = stash->info_ptr;
 | 
      
        |       stash->syms = symbols;
 |       stash->syms = symbols;
 | 
      
        |       stash->bfd_ptr = debug_bfd;
 |       stash->bfd_ptr = debug_bfd;
 | 
      
        |   |  
 | 
      
        |   |   return TRUE;
 | 
      
        |   | }
 | 
      
        |   |  
 | 
      
        |   | /* 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.
 | 
      
        |   |    DEBUG_SECTIONS contains the name of the dwarf debug sections.
 | 
      
        |   |    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.  */
 | 
      
        |   |  
 | 
      
        |   | static bfd_boolean
 | 
      
        |   | find_line (bfd *abfd,
 | 
      
        |   |            const struct dwarf_debug_section *debug_sections,
 | 
      
        |   |            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,
 | 
      
        |   |      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;
 | 
      
        |   |   bfd_vma found = FALSE;
 | 
      
        |   |   bfd_boolean do_line;
 | 
      
        |   |  
 | 
      
        |   |   *filename_ptr = NULL;
 | 
      
        |   |   if (functionname_ptr != NULL)
 | 
      
        |   |     *functionname_ptr = NULL;
 | 
      
        |   |   *linenumber_ptr = 0;
 | 
      
        |   |  
 | 
      
        |   |   if (! _bfd_dwarf2_slurp_debug_info (abfd, NULL,
 | 
      
        |   |                                       debug_sections, symbols, pinfo))
 | 
      
        |   |     return FALSE;
 | 
      
        |   |  
 | 
      
        |   |   stash = (struct dwarf2_debug *) *pinfo;
 | 
      
        |   |  
 | 
      
        |   |   /* In a relocatable file, 2 functions may have the same address.
 | 
      
        |   |      We change the section vma so that they won't overlap.  */
 | 
      
        |   |   if ((abfd->flags & (EXEC_P | DYNAMIC)) == 0)
 | 
      
        |   |     {
 | 
      
        |   |       if (! place_sections (abfd, stash))
 | 
      
        |   |         return FALSE;
 | 
      
        |     }
 |     }
 | 
      
        |  
 |  
 | 
      
        |   |   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
 | 
      
        |   |     addr += section->vma;
 | 
      
        |   |  
 | 
      
        |   /* A null info_ptr indicates that there is no dwarf2 info
 |   /* A null info_ptr indicates that there is no dwarf2 info
 | 
      
        |      (or that an error occured while setting up the stash).  */
 |      (or that an error occured while setting up the stash).  */
 | 
      
        |   if (! stash->info_ptr)
 |   if (! stash->info_ptr)
 | 
      
        |     goto done;
 |     return FALSE;
 | 
      
        |  
 |  
 | 
      
        |   stash->inliner_chain = NULL;
 |   stash->inliner_chain = NULL;
 | 
      
        |  
 |  
 | 
      
        |   /* Check the previously read comp. units first.  */
 |   /* Check the previously read comp. units first.  */
 | 
      
        |   if (do_line)
 |   if (do_line)
 | 
      
        | Line 3525... | Line 3541... | 
      
        |  
 |  
 | 
      
        |   return FALSE;
 |   return FALSE;
 | 
      
        | }
 | }
 | 
      
        |  
 |  
 | 
      
        | void
 | void
 | 
      
        | _bfd_dwarf2_cleanup_debug_info (bfd *abfd)
 | _bfd_dwarf2_cleanup_debug_info (bfd *abfd, void **pinfo)
 | 
      
        | {
 | {
 | 
      
        |   |   struct dwarf2_debug *stash = (struct dwarf2_debug *) *pinfo;;
 | 
      
        |   struct comp_unit *each;
 |   struct comp_unit *each;
 | 
      
        |   struct dwarf2_debug *stash;
 |   | 
      
        |  
 |   | 
      
        |   if (abfd == NULL || elf_tdata (abfd) == NULL)
 |   | 
      
        |     return;
 |   | 
      
        |  
 |   | 
      
        |   stash = (struct dwarf2_debug *) elf_tdata (abfd)->dwarf2_find_line_info;
 |   | 
      
        |  
 |  
 | 
      
        |   if (stash == NULL)
 |   if (abfd == NULL || stash == NULL)
 | 
      
        |     return;
 |     return;
 | 
      
        |  
 |  
 | 
      
        |   for (each = stash->all_comp_units; each; each = each->next_unit)
 |   for (each = stash->all_comp_units; each; each = each->next_unit)
 | 
      
        |     {
 |     {
 | 
      
        |       struct abbrev_info **abbrevs = each->abbrevs;
 |       struct abbrev_info **abbrevs = each->abbrevs;
 |