+ free (syms);
+ syms = NULL;
+ }
+ if (syms == NULL)
+ {
+ long symsize;
+
+ symsize = bfd_get_symtab_upper_bound (abfd);
+ if (symsize < 0)
+ bfd_fatal (bfd_get_filename (abfd));
+ syms = (asymbol **) xmalloc (symsize);
+ symcount = bfd_canonicalize_symtab (abfd, syms);
+ if (symcount < 0)
+ bfd_fatal (bfd_get_filename (abfd));
+ lineno_cache_bfd = abfd;
+ }
+
+ if (bfd_is_und_section (bfd_asymbol_section (sym)))
+ {
+ static asection **secs;
+ static arelent ***relocs;
+ static long *relcount;
+ static unsigned int seccount;
+ unsigned int i;
+ const char *symname;
+
+ /* For an undefined symbol, we try to find a reloc for the
+ symbol, and print the line number of the reloc. */
+ if (abfd != lineno_cache_rel_bfd && relocs != NULL)
+ {
+ for (i = 0; i < seccount; i++)
+ if (relocs[i] != NULL)
+ free (relocs[i]);
+ free (secs);
+ free (relocs);
+ free (relcount);
+ secs = NULL;
+ relocs = NULL;
+ relcount = NULL;
+ }
+
+ if (relocs == NULL)
+ {
+ struct get_relocs_info rinfo;
+
+ seccount = bfd_count_sections (abfd);
+
+ secs = (asection **) xmalloc (seccount * sizeof *secs);
+ relocs = (arelent ***) xmalloc (seccount * sizeof *relocs);
+ relcount = (long *) xmalloc (seccount * sizeof *relcount);
+
+ rinfo.secs = secs;
+ rinfo.relocs = relocs;
+ rinfo.relcount = relcount;
+ rinfo.syms = syms;
+ bfd_map_over_sections (abfd, get_relocs, (void *) &rinfo);
+ lineno_cache_rel_bfd = abfd;
+ }
+
+ symname = bfd_asymbol_name (sym);
+ for (i = 0; i < seccount; i++)
+ {
+ long j;
+
+ for (j = 0; j < relcount[i]; j++)
+ {
+ arelent *r;
+
+ r = relocs[i][j];
+ if (r->sym_ptr_ptr != NULL
+ && (*r->sym_ptr_ptr)->section == sym->section
+ && (*r->sym_ptr_ptr)->value == sym->value
+ && strcmp (symname,
+ bfd_asymbol_name (*r->sym_ptr_ptr)) == 0
+ && bfd_find_nearest_line (abfd, secs[i], syms,
+ r->address, &filename,
+ &functionname, &lineno)
+ && filename != NULL)
+ {
+ /* We only print the first one we find. */
+ printf ("\t%s:%u", filename, lineno);
+ i = seccount;
+ break;
+ }
+ }
+ }
+ }
+ else if (bfd_asymbol_section (sym)->owner == abfd)
+ {
+ if ((bfd_find_line (abfd, syms, sym, &filename, &lineno)
+ || bfd_find_nearest_line (abfd, bfd_asymbol_section (sym),
+ syms, sym->value, &filename,
+ &functionname, &lineno))
+ && filename != NULL
+ && lineno != 0)
+ printf ("\t%s:%u", filename, lineno);