bfd/
authorAlan Modra <amodra@gmail.com>
Sun, 17 Aug 2008 03:12:50 +0000 (03:12 +0000)
committerAlan Modra <amodra@gmail.com>
Sun, 17 Aug 2008 03:12:50 +0000 (03:12 +0000)
* bfd.c (struct _bfd): Correct outsymbols comment.
* bfd-in2.h: Regenerate.
* linker.c (bfd_generic_link_read_symbols): Renamed from..
(generic_link_read_symbols): ..this, and made global.

include/
* bfdlink.h (bfd_generic_link_read_symbols): Declare.
ld/
PR 6478
* ldcref.c (check_local_sym_xref): Use bfd_generic_link_read_symbols.
Don't free symbol pointer array.
(check_refs): Likewise.
* ldmain.c (warning_callback): Likewise.
* ldmisc.c (vfinfo): Likewise.
* pe-dll.c (process_def_file): Likewise.
(pe_walk_relocs_of_symbol, generate_reloc): Likewise.
* emultempl/pe.em (pe_find_data_imports): Likewise.
(gld_${EMULATION_NAME}_after_open): Likewise.
* emultempl/pep.em (pep_find_data_imports): Likewise.
(gld_${EMULATION_NAME}_after_open): Likewise.
* ldlang.h (lang_input_statement_type): Delete asymbols, symbol_count,
passive_position, closed.
* ldlang.c (new_afile): Don't set asymbols and symbol_count.
* ldmain.c (add_archive_element): xcalloc lang_input_statement_type.

15 files changed:
bfd/ChangeLog
bfd/bfd-in2.h
bfd/bfd.c
bfd/linker.c
include/ChangeLog
include/bfdlink.h
ld/ChangeLog
ld/emultempl/pe.em
ld/emultempl/pep.em
ld/ldcref.c
ld/ldlang.c
ld/ldlang.h
ld/ldmain.c
ld/ldmisc.c
ld/pe-dll.c

index a4d9667ba970ac64940d244730e6808be9213c9a..a85352579fd1d8a511e8b9778d0c976403b5e6cf 100644 (file)
@@ -1,3 +1,10 @@
+2008-08-17  Alan Modra  <amodra@bigpond.net.au>
+
+       * bfd.c (struct _bfd): Correct outsymbols comment.
+       * bfd-in2.h: Regenerate.
+       * linker.c (bfd_generic_link_read_symbols): Renamed from..
+       (generic_link_read_symbols): ..this, and made global.
+
 2008-08-15  Alan Modra  <amodra@bigpond.net.au>
 
        PR 6526
index 8868e7d26429e8cff28c1551d1305143895912da..a39c46162f3aa680a1185cb31114abcb33114963 100644 (file)
@@ -4712,7 +4712,8 @@ struct bfd
   /* Used for input and output.  */
   unsigned int symcount;
 
-  /* Symbol table for output BFD (with symcount entries).  */
+  /* Symbol table for output BFD (with symcount entries).
+     Also used by the linker to cache input BFD symbols.  */
   struct bfd_symbol  **outsymbols;
 
   /* Used for slurped dynamic symbol tables.  */
index ed89e664cc79ad6e6a1f9ab545d078d5939dcece..1ffd7d05b1d54c69c47dc444f87bfaa8e63bcf4b 100644 (file)
--- a/bfd/bfd.c
+++ b/bfd/bfd.c
@@ -176,7 +176,8 @@ CODE_FRAGMENT
 .  {* Used for input and output.  *}
 .  unsigned int symcount;
 .
-.  {* Symbol table for output BFD (with symcount entries).  *}
+.  {* Symbol table for output BFD (with symcount entries).
+.     Also used by the linker to cache input BFD symbols.  *}
 .  struct bfd_symbol  **outsymbols;
 .
 .  {* Used for slurped dynamic symbol tables.  *}
index 327426e3c519d0efa77ac98b2cf903c0948d635d..baf280c7a24bf60ea1734af344e865fdea6d230b 100644 (file)
@@ -737,8 +737,8 @@ _bfd_generic_link_hash_table_free (struct bfd_link_hash_table *hash)
    the hash table pointing to different instances of the symbol
    structure.  */
 
-static bfd_boolean
-generic_link_read_symbols (bfd *abfd)
+bfd_boolean
+bfd_generic_link_read_symbols (bfd *abfd)
 {
   if (bfd_get_outsymbols (abfd) == NULL)
     {
@@ -834,7 +834,7 @@ generic_link_add_object_symbols (bfd *abfd,
   bfd_size_type symcount;
   struct bfd_symbol **outsyms;
 
-  if (! generic_link_read_symbols (abfd))
+  if (!bfd_generic_link_read_symbols (abfd))
     return FALSE;
   symcount = _bfd_generic_link_get_symcount (abfd);
   outsyms = _bfd_generic_link_get_symbols (abfd);
@@ -1164,7 +1164,7 @@ generic_link_check_archive_element (bfd *abfd,
 
   *pneeded = FALSE;
 
-  if (! generic_link_read_symbols (abfd))
+  if (!bfd_generic_link_read_symbols (abfd))
     return FALSE;
 
   pp = _bfd_generic_link_get_symbols (abfd);
@@ -2159,7 +2159,7 @@ _bfd_generic_link_output_symbols (bfd *output_bfd,
   asymbol **sym_ptr;
   asymbol **sym_end;
 
-  if (! generic_link_read_symbols (input_bfd))
+  if (!bfd_generic_link_read_symbols (input_bfd))
     return FALSE;
 
   /* Create a filename symbol if we are supposed to.  */
@@ -2752,7 +2752,7 @@ default_indirect_link_order (bfd *output_bfd,
         have retrieved them by this point, but we are being called by
         a specific linker, presumably because we are linking
         different types of object files together.  */
-      if (! generic_link_read_symbols (input_bfd))
+      if (!bfd_generic_link_read_symbols (input_bfd))
        return FALSE;
 
       /* Since we have been called by a specific linker, rather than
index a1e31a64db0ca195a6068b807e8761686049e161..c86f60089a9b9f1230dcf5a6833a0c6198355db1 100644 (file)
@@ -1,3 +1,7 @@
+2008-08-17  Alan Modra  <amodra@bigpond.net.au>
+
+       * bfdlink.h (bfd_generic_link_read_symbols): Declare.
+
 2008-08-08  Anatoly Sokolov  <aesok@post.ru>
 
        * elf/avr.h (E_AVR_MACH_AVR25, E_AVR_MACH_AVR31,
index e68331028396acd91c7e2ae8a069cff216904b76..d27b5388d3b61c9c2c7ed432902d1e96bf6431fd 100644 (file)
@@ -198,6 +198,9 @@ extern void bfd_link_add_undef
 extern void bfd_link_repair_undef_list
   (struct bfd_link_hash_table *table);
 
+/* Read symbols and cache symbol pointer array in outsymbols.  */
+extern bfd_boolean bfd_generic_link_read_symbols (bfd *);
+
 struct bfd_sym_chain
 {
   struct bfd_sym_chain *next;
index 0e718a8a1104cb5c23cb34b367f8fd5d71808f6b..213b5f026d15b88ff261e15240072aaeabbf0cbc 100644 (file)
@@ -1,3 +1,22 @@
+2008-08-17  Alan Modra  <amodra@bigpond.net.au>
+
+       PR 6478
+       * ldcref.c (check_local_sym_xref): Use bfd_generic_link_read_symbols.
+       Don't free symbol pointer array.
+       (check_refs): Likewise.
+       * ldmain.c (warning_callback): Likewise.
+       * ldmisc.c (vfinfo): Likewise.
+       * pe-dll.c (process_def_file): Likewise.
+       (pe_walk_relocs_of_symbol, generate_reloc): Likewise.
+       * emultempl/pe.em (pe_find_data_imports): Likewise.
+       (gld_${EMULATION_NAME}_after_open): Likewise.
+       * emultempl/pep.em (pep_find_data_imports): Likewise.
+       (gld_${EMULATION_NAME}_after_open): Likewise.
+       * ldlang.h (lang_input_statement_type): Delete asymbols, symbol_count,
+       passive_position, closed.
+       * ldlang.c (new_afile): Don't set asymbols and symbol_count.
+       * ldmain.c (add_archive_element): xcalloc lang_input_statement_type.
+
 2008-08-15  Alan Modra  <amodra@bigpond.net.au>
 
        PR 6526
index 08cfcfc24a692e7d70eabafc6e8f02b46cad9fdf..865cfaaeb02e5b401cd7b0a34907f353516ecbd3 100644 (file)
@@ -922,7 +922,7 @@ pe_find_data_imports (void)
            {
              bfd *b = sym->u.def.section->owner;
              asymbol **symbols;
-             int nsyms, symsize, i;
+             int nsyms, i;
 
              if (link_info.pei386_auto_import == -1)
                {
@@ -940,9 +940,14 @@ This should work unless it involves constant data structures referencing symbols
                    }
                }
 
-             symsize = bfd_get_symtab_upper_bound (b);
-             symbols = (asymbol **) xmalloc (symsize);
-             nsyms = bfd_canonicalize_symtab (b, symbols);
+             if (!bfd_generic_link_read_symbols (b))
+               {
+                 einfo (_("%B%F: could not read symbols: %E\n"), b);
+                 return;
+               }
+
+             symbols = bfd_get_outsymbols (b);
+             nsyms = bfd_get_symcount (b);
 
              for (i = 0; i < nsyms; i++)
                {
@@ -1094,26 +1099,22 @@ gld_${EMULATION_NAME}_after_open (void)
                for (sec = is->the_bfd->sections; sec; sec = sec->next)
                  {
                    int i;
-                   long symsize;
                    long relsize;
                    asymbol **symbols;
                    arelent **relocs;
                    int nrelocs;
 
-                   symsize = bfd_get_symtab_upper_bound (is->the_bfd);
-                   if (symsize < 1)
-                     break;
                    relsize = bfd_get_reloc_upper_bound (is->the_bfd, sec);
                    if (relsize < 1)
                      break;
 
-                   symbols = (asymbol **) xmalloc (symsize);
-                   symsize = bfd_canonicalize_symtab (is->the_bfd, symbols);
-                   if (symsize < 0)
+                   if (!bfd_generic_link_read_symbols (is->the_bfd))
                      {
-                       einfo ("%X%P: unable to process symbols: %E");
+                       einfo (_("%B%F: could not read symbols: %E\n"),
+                              is->the_bfd);
                        return;
                      }
+                   symbols = bfd_get_outsymbols (is->the_bfd);
 
                    relocs = (arelent **) xmalloc ((size_t) relsize);
                    nrelocs = bfd_canonicalize_reloc (is->the_bfd, sec,
@@ -1309,16 +1310,20 @@ gld_${EMULATION_NAME}_after_open (void)
 
            if (is_imp && stub_sec)
              {
-               long symsize;
                asymbol **symbols;
-               long src_count;
+               long nsyms, src_count;
                struct bfd_link_hash_entry * blhe;
 
-               symsize = bfd_get_symtab_upper_bound (is->the_bfd);
-               symbols = xmalloc (symsize);
-               symsize = bfd_canonicalize_symtab (is->the_bfd, symbols);
+               if (!bfd_generic_link_read_symbols (is->the_bfd))
+                 {
+                   einfo (_("%B%F: could not read symbols: %E\n"),
+                          is->the_bfd);
+                   return;
+                 }
+               symbols = bfd_get_outsymbols (is->the_bfd);
+               nsyms = bfd_get_symcount (is->the_bfd);
 
-               for (src_count = 0; src_count < symsize; src_count++)
+               for (src_count = 0; src_count < nsyms; src_count++)
                  {
                    if (symbols[src_count]->section->id == stub_sec->id)
                      {
@@ -1335,7 +1340,6 @@ gld_${EMULATION_NAME}_after_open (void)
                          stub_sec->flags |= SEC_EXCLUDE;
                      }
                  }
-               free (symbols);
              }
          }
       }
index 2fae386650a2e9f617da788facc2b0e0ec0ff7d5..21bcf0151475608d0b0ae099aec6526b07b270c8 100644 (file)
@@ -881,7 +881,7 @@ pep_find_data_imports (void)
            {
              bfd *b = sym->u.def.section->owner;
              asymbol **symbols;
-             int nsyms, symsize, i;
+             int nsyms, i;
 
              if (link_info.pei386_auto_import == -1)
                {
@@ -899,9 +899,14 @@ This should work unless it involves constant data structures referencing symbols
                    }
                }
 
-             symsize = bfd_get_symtab_upper_bound (b);
-             symbols = xmalloc (symsize);
-             nsyms = bfd_canonicalize_symtab (b, symbols);
+             if (!bfd_generic_link_read_symbols (b))
+               {
+                 einfo (_("%B%F: could not read symbols: %E\n"), b);
+                 return;
+               }
+
+             symbols = bfd_get_outsymbols (b);
+             nsyms = bfd_get_symcount (b);
 
              for (i = 0; i < nsyms; i++)
                {
@@ -1032,26 +1037,22 @@ gld_${EMULATION_NAME}_after_open (void)
                for (sec = is->the_bfd->sections; sec; sec = sec->next)
                  {
                    int i;
-                   long symsize;
                    long relsize;
                    asymbol **symbols;
                    arelent **relocs;
                    int nrelocs;
 
-                   symsize = bfd_get_symtab_upper_bound (is->the_bfd);
-                   if (symsize < 1)
-                     break;
                    relsize = bfd_get_reloc_upper_bound (is->the_bfd, sec);
                    if (relsize < 1)
                      break;
 
-                   symbols = xmalloc (symsize);
-                   symsize = bfd_canonicalize_symtab (is->the_bfd, symbols);
-                   if (symsize < 0)
+                   if (!bfd_generic_link_read_symbols (is->the_bfd))
                      {
-                       einfo ("%X%P: unable to process symbols: %E");
+                       einfo (_("%B%F: could not read symbols: %E\n"),
+                              is->the_bfd);
                        return;
                      }
+                   symbols = bfd_get_outsymbols (is->the_bfd);
 
                    relocs = xmalloc ((size_t) relsize);
                    nrelocs = bfd_canonicalize_reloc (is->the_bfd, sec,
index 890b61cbd591a97a2b5b86a0aa7aba75f7e0b007..3fcaafe09003e463d072621c79bbf6c2664bee27 100644 (file)
@@ -478,36 +478,16 @@ static void
 check_local_sym_xref (lang_input_statement_type *statement)
 {
   bfd *abfd;
-  lang_input_statement_type *li;
-  asymbol **asymbols, **syms;
+  asymbol **syms;
 
   abfd = statement->the_bfd;
   if (abfd == NULL)
     return;
 
-  li = abfd->usrdata;
-  if (li != NULL && li->asymbols != NULL)
-    asymbols = li->asymbols;
-  else
-    {
-      long symsize;
-      long symbol_count;
-
-      symsize = bfd_get_symtab_upper_bound (abfd);
-      if (symsize < 0)
-       einfo (_("%B%F: could not read symbols; %E\n"), abfd);
-      asymbols = xmalloc (symsize);
-      symbol_count = bfd_canonicalize_symtab (abfd, asymbols);
-      if (symbol_count < 0)
-       einfo (_("%B%F: could not read symbols: %E\n"), abfd);
-      if (li != NULL)
-       {
-         li->asymbols = asymbols;
-         li->symbol_count = symbol_count;
-       }
-    }
+  if (!bfd_generic_link_read_symbols (abfd))
+    einfo (_("%B%F: could not read symbols: %E\n"), abfd);
 
-  for (syms = asymbols; *syms; ++syms)
+  for (syms = bfd_get_outsymbols (abfd); *syms; ++syms)
     {
       asymbol *sym = *syms;
       if (sym->flags & (BSF_GLOBAL | BSF_WARNING | BSF_INDIRECT | BSF_FILE))
@@ -529,9 +509,6 @@ check_local_sym_xref (lang_input_statement_type *statement)
                check_refs (symname, FALSE, sym->section, abfd, ncrs);
        }
     }
-
-  if (li == NULL)
-    free (asymbols);
 }
 
 /* Check one symbol to see if it is a prohibited cross reference.  */
@@ -597,8 +574,6 @@ check_refs (const char *name,
            bfd *abfd,
            struct lang_nocrossrefs *ncrs)
 {
-  lang_input_statement_type *li;
-  asymbol **asymbols;
   struct check_refs_info info;
 
   /* We need to look through the relocations for this BFD, to see
@@ -607,37 +582,15 @@ check_refs (const char *name,
      the BFD in which the symbol is defined, since even a single
      BFD might contain a prohibited cross reference.  */
 
-  li = abfd->usrdata;
-  if (li != NULL && li->asymbols != NULL)
-    asymbols = li->asymbols;
-  else
-    {
-      long symsize;
-      long symbol_count;
-
-      symsize = bfd_get_symtab_upper_bound (abfd);
-      if (symsize < 0)
-       einfo (_("%B%F: could not read symbols; %E\n"), abfd);
-      asymbols = xmalloc (symsize);
-      symbol_count = bfd_canonicalize_symtab (abfd, asymbols);
-      if (symbol_count < 0)
-       einfo (_("%B%F: could not read symbols: %E\n"), abfd);
-      if (li != NULL)
-       {
-         li->asymbols = asymbols;
-         li->symbol_count = symbol_count;
-       }
-    }
+  if (!bfd_generic_link_read_symbols (abfd))
+    einfo (_("%B%F: could not read symbols: %E\n"), abfd);
 
   info.sym_name = name;
   info.global = global;
   info.defsec = sec;
   info.ncrs = ncrs;
-  info.asymbols = asymbols;
+  info.asymbols = bfd_get_outsymbols (abfd);
   bfd_map_over_sections (abfd, check_reloc_refs, &info);
-
-  if (li == NULL)
-    free (asymbols);
 }
 
 /* This is called via bfd_map_over_sections.  INFO->SYM_NAME is a symbol
index 2f5c2137f6b7300549b79ea259b28be6777f955c..e9916467d959b68c0bfb8c1fd5a840fe575b905a 100644 (file)
@@ -1033,10 +1033,8 @@ new_afile (const char *name,
       FAIL ();
     }
   p->the_bfd = NULL;
-  p->asymbols = NULL;
   p->next_real_file = NULL;
   p->next = NULL;
-  p->symbol_count = 0;
   p->dynamic = config.dynamic_link;
   p->add_needed = add_needed;
   p->as_needed = as_needed;
index 6de4267e98d71337988739121edc059648c3bad8..48461977c8043c6bb4b4134804a60758bb3b16c4 100644 (file)
@@ -232,12 +232,6 @@ typedef struct lang_input_statement_struct
 
   bfd *the_bfd;
 
-  file_ptr passive_position;
-
-  /* Symbol table of the file.  */
-  asymbol **asymbols;
-  unsigned int symbol_count;
-
   /* Point to the next file - whatever it is, wanders up and down
      archives */
   union lang_statement_union *next;
@@ -247,7 +241,6 @@ typedef struct lang_input_statement_struct
 
   const char *target;
 
-  unsigned int closed : 1;
   unsigned int is_archive : 1;
 
   /* 1 means search a set of directories for this file.  */
index bf3c0e6ded2d158575bc789c8a39f85175ab81e5..706058728403e78e99d9c0a5296f2c76595d9610 100644 (file)
@@ -778,21 +778,10 @@ add_archive_element (struct bfd_link_info *info,
 {
   lang_input_statement_type *input;
 
-  input = xmalloc (sizeof (lang_input_statement_type));
+  input = xcalloc (1, sizeof (lang_input_statement_type));
   input->filename = abfd->filename;
   input->local_sym_name = abfd->filename;
   input->the_bfd = abfd;
-  input->asymbols = NULL;
-  input->next = NULL;
-  input->just_syms_flag = FALSE;
-  input->loaded = FALSE;
-  input->search_dirs_flag = FALSE;
-
-  /* FIXME: The following fields are not set: header.next,
-     header.type, closed, passive_position, symbol_count,
-     next_real_file, is_archive, target, real.  This bit of code is
-     from the old decode_library_subfile function.  I don't know
-     whether any of those fields matters.  */
 
   ldlang_add_file (input);
 
@@ -1107,45 +1096,22 @@ warning_callback (struct bfd_link_info *info ATTRIBUTE_UNUSED,
     einfo ("%B: %s%s\n", abfd, _("warning: "), warning);
   else
     {
-      lang_input_statement_type *entry;
-      asymbol **asymbols;
       struct warning_callback_info info;
 
       /* Look through the relocs to see if we can find a plausible
         address.  */
-      entry = (lang_input_statement_type *) abfd->usrdata;
-      if (entry != NULL && entry->asymbols != NULL)
-       asymbols = entry->asymbols;
-      else
-       {
-         long symsize;
-         long symbol_count;
-
-         symsize = bfd_get_symtab_upper_bound (abfd);
-         if (symsize < 0)
-           einfo (_("%B%F: could not read symbols: %E\n"), abfd);
-         asymbols = xmalloc (symsize);
-         symbol_count = bfd_canonicalize_symtab (abfd, asymbols);
-         if (symbol_count < 0)
-           einfo (_("%B%F: could not read symbols: %E\n"), abfd);
-         if (entry != NULL)
-           {
-             entry->asymbols = asymbols;
-             entry->symbol_count = symbol_count;
-           }
-       }
+
+      if (!bfd_generic_link_read_symbols (abfd))
+       einfo (_("%B%F: could not read symbols: %E\n"), abfd);
 
       info.found = FALSE;
       info.warning = warning;
       info.symbol = symbol;
-      info.asymbols = asymbols;
+      info.asymbols = bfd_get_outsymbols (abfd);
       bfd_map_over_sections (abfd, warning_find_reloc, &info);
 
       if (! info.found)
        einfo ("%B: %s%s\n", abfd, _("warning: "), warning);
-
-      if (entry == NULL)
-       free (asymbols);
     }
 
   return TRUE;
index bdae82e4ae90c8adb2f715ae4d4c8aa2fa67ff6d..d49cf178125b3f4a7069d81a758e5a6fa863d28d 100644 (file)
@@ -269,8 +269,7 @@ vfinfo (FILE *fp, const char *fmt, va_list arg, bfd_boolean is_warning)
                bfd *abfd;
                asection *section;
                bfd_vma offset;
-               lang_input_statement_type *entry;
-               asymbol **asymbols;
+               asymbol **asymbols = NULL;
                const char *filename;
                const char *functionname;
                unsigned int linenumber;
@@ -280,35 +279,12 @@ vfinfo (FILE *fp, const char *fmt, va_list arg, bfd_boolean is_warning)
                section = va_arg (arg, asection *);
                offset = va_arg (arg, bfd_vma);
 
-               if (abfd == NULL)
-                 {
-                   entry = NULL;
-                   asymbols = NULL;
-                 }
-               else
+               if (abfd != NULL)
                  {
-                   entry = (lang_input_statement_type *) abfd->usrdata;
-                   if (entry != (lang_input_statement_type *) NULL
-                       && entry->asymbols != (asymbol **) NULL)
-                     asymbols = entry->asymbols;
-                   else
-                     {
-                       long symsize;
-                       long sym_count;
-
-                       symsize = bfd_get_symtab_upper_bound (abfd);
-                       if (symsize < 0)
-                         einfo (_("%B%F: could not read symbols\n"), abfd);
-                       asymbols = xmalloc (symsize);
-                       sym_count = bfd_canonicalize_symtab (abfd, asymbols);
-                       if (sym_count < 0)
-                         einfo (_("%B%F: could not read symbols\n"), abfd);
-                       if (entry != (lang_input_statement_type *) NULL)
-                         {
-                           entry->asymbols = asymbols;
-                           entry->symbol_count = sym_count;
-                         }
-                     }
+                   if (!bfd_generic_link_read_symbols (abfd))
+                     einfo (_("%B%F: could not read symbols: %E\n"), abfd);
+
+                   asymbols = bfd_get_outsymbols (abfd);
                  }
 
                /* The GNU Coding Standard requires that error messages
@@ -375,9 +351,6 @@ vfinfo (FILE *fp, const char *fmt, va_list arg, bfd_boolean is_warning)
                else
                  lfinfo (fp, "%B:(%A+0x%v)", abfd, section, offset);
 
-               if (asymbols != NULL && entry == NULL)
-                 free (asymbols);
-
                if (discard_last)
                  {
                    last_bfd = NULL;
index c6c656a230d20d104cb0187df6e7ba3b7896c774..ea84999cef7f82ac14cf075375b41e4309a2b2ed 100644 (file)
@@ -615,11 +615,16 @@ process_def_file (bfd *abfd ATTRIBUTE_UNUSED, struct bfd_link_info *info)
       for (b = info->input_bfds; b; b = b->link_next)
        {
          asymbol **symbols;
-         int nsyms, symsize;
+         int nsyms;
 
-         symsize = bfd_get_symtab_upper_bound (b);
-         symbols = xmalloc (symsize);
-         nsyms = bfd_canonicalize_symtab (b, symbols);
+         if (!bfd_generic_link_read_symbols (b))
+           {
+             einfo (_("%B%F: could not read symbols: %E\n"), b);
+             return;
+           }
+
+         symbols = bfd_get_outsymbols (b);
+         nsyms = bfd_get_symcount (b);
 
          for (j = 0; j < nsyms; j++)
            {
@@ -1141,11 +1146,16 @@ pe_walk_relocs_of_symbol (struct bfd_link_info *info,
   for (b = info->input_bfds; b; b = b->link_next)
     {
       asymbol **symbols;
-      int nsyms, symsize;
+      int nsyms;
 
-      symsize = bfd_get_symtab_upper_bound (b);
-      symbols = xmalloc (symsize);
-      nsyms   = bfd_canonicalize_symtab (b, symbols);
+      if (!bfd_generic_link_read_symbols (b))
+       {
+         einfo (_("%B%F: could not read symbols: %E\n"), b);
+         return;
+       }
+
+      symbols = bfd_get_outsymbols (b);
+      nsyms = bfd_get_symcount (b);
 
       for (s = b->sections; s; s = s->next)
        {
@@ -1215,7 +1225,7 @@ generate_reloc (bfd *abfd, struct bfd_link_info *info)
        {
          bfd_vma sec_vma = s->output_section->vma + s->output_offset;
          asymbol **symbols;
-         int nsyms, symsize;
+         int nsyms;
 
          /* If it's not loaded, we don't need to relocate it this way.  */
          if (!(s->output_section->flags & SEC_LOAD))
@@ -1235,10 +1245,14 @@ generate_reloc (bfd *abfd, struct bfd_link_info *info)
              continue;
            }
 
-         symsize = bfd_get_symtab_upper_bound (b);
-         symbols = xmalloc (symsize);
-         nsyms = bfd_canonicalize_symtab (b, symbols);
+         if (!bfd_generic_link_read_symbols (b))
+           {
+             einfo (_("%B%F: could not read symbols: %E\n"), b);
+             return;
+           }
 
+         symbols = bfd_get_outsymbols (b);
+         nsyms = bfd_get_symcount (b);
          relsize = bfd_get_reloc_upper_bound (b, s);
          relocs = xmalloc (relsize);
          nrelocs = bfd_canonicalize_reloc (b, s, relocs, symbols);