2009-06-18 H.J. Lu <hongjiu.lu@intel.com>
authorH.J. Lu <hjl.tools@gmail.com>
Thu, 18 Jun 2009 12:49:41 +0000 (12:49 +0000)
committerH.J. Lu <hjl.tools@gmail.com>
Thu, 18 Jun 2009 12:49:41 +0000 (12:49 +0000)
* elf32-i386.c (elf_i386_check_relocs): Cache or free isymbuf.
* elf64-x86-64.c (elf64_x86_64_check_relocs): Likewise.

bfd/ChangeLog
bfd/elf32-i386.c
bfd/elf64-x86-64.c

index 8f3edb08d724e75c1357c6ef08e276361afd6b49..edfe50f07be64959befcf18d98cfdc574c27fb8e 100644 (file)
@@ -1,3 +1,8 @@
+2009-06-18  H.J. Lu  <hongjiu.lu@intel.com>
+
+       * elf32-i386.c (elf_i386_check_relocs): Cache or free isymbuf.
+       * elf64-x86-64.c (elf64_x86_64_check_relocs): Likewise.
+
 2009-06-18  Nick Clifton  <nickc@redhat.com>
 
        * elflink.c (elf_link_sort_relocs): Return early if there are no
index 32ea2873053e057532fdacbabc83ee0b7d834cbb..8dd3b8a68c885d5e681606996ca601f1e993ded8 100644 (file)
@@ -1313,7 +1313,7 @@ elf_i386_check_relocs (bfd *abfd,
              h = elf_i386_get_local_sym_hash (htab, abfd, rel,
                                                   TRUE);
              if (h == NULL)
-               return FALSE;
+               goto error_return;
              
              /* Fake a STT_GNU_IFUNC symbol.  */
              h->type = STT_GNU_IFUNC;
@@ -1350,7 +1350,7 @@ elf_i386_check_relocs (bfd *abfd,
            case R_386_GOT32:
            case R_386_GOTOFF:
              if (!_bfd_elf_create_ifunc_sections (abfd, info))
-               return FALSE;
+               goto error_return;
              break;
            }
 
@@ -1380,7 +1380,7 @@ elf_i386_check_relocs (bfd *abfd,
                      ? h->root.root.string : "a local symbol"),
                     __FUNCTION__);
                  bfd_set_error (bfd_error_bad_value);
-                 return FALSE;
+                 goto error_return;
 
                case R_386_32:
                  h->non_got_ref = 1;
@@ -1394,7 +1394,7 @@ elf_i386_check_relocs (bfd *abfd,
                        (abfd, info, sec, sreloc,
                         &((struct elf_i386_link_hash_entry *) h)->dyn_relocs);
                      if (sreloc == NULL)
-                       return FALSE;
+                       goto error_return;
                    }
                  break;
 
@@ -1411,7 +1411,7 @@ elf_i386_check_relocs (bfd *abfd,
                  if (htab->elf.sgot == NULL
                      && !_bfd_elf_create_got_section (htab->elf.dynobj,
                                                       info))
-                   return FALSE;
+                   goto error_return;
                  break;
                }
 
@@ -1423,7 +1423,7 @@ elf_i386_check_relocs (bfd *abfd,
                                     symtab_hdr, sym_hashes,
                                     &r_type, GOT_UNKNOWN,
                                     rel, rel_end, h)) 
-       return FALSE;
+       goto error_return;
 
       switch (r_type)
        {
@@ -1504,7 +1504,7 @@ elf_i386_check_relocs (bfd *abfd,
                             + sizeof (bfd_vma) + sizeof(char));
                    local_got_refcounts = bfd_zalloc (abfd, size);
                    if (local_got_refcounts == NULL)
-                     return FALSE;
+                     goto error_return;
                    elf_local_got_refcounts (abfd) = local_got_refcounts;
                    elf_i386_local_tlsdesc_gotent (abfd)
                      = (bfd_vma *) (local_got_refcounts + symtab_hdr->sh_info);
@@ -1535,7 +1535,7 @@ elf_i386_check_relocs (bfd *abfd,
                         "thread local symbol"),
                       abfd,
                       h ? h->root.root.string : "<local>");
-                   return FALSE;
+                   goto error_return;
                  }
              }
 
@@ -1557,7 +1557,7 @@ elf_i386_check_relocs (bfd *abfd,
              if (htab->elf.dynobj == NULL)
                htab->elf.dynobj = abfd;
              if (!_bfd_elf_create_got_section (htab->elf.dynobj, info))
-               return FALSE;
+               goto error_return;
            }
          if (r_type != R_386_TLS_IE)
            break;
@@ -1639,7 +1639,7 @@ elf_i386_check_relocs (bfd *abfd,
                    (sec, htab->elf.dynobj, 2, abfd, /*rela?*/ FALSE);
 
                  if (sreloc == NULL)
-                   return FALSE;
+                   goto error_return;
                }
 
              /* If this is a global symbol, we count the number of
@@ -1659,7 +1659,7 @@ elf_i386_check_relocs (bfd *abfd,
                  s = bfd_section_from_r_symndx (abfd, &htab->sym_sec,
                                                 sec, r_symndx);
                  if (s == NULL)
-                   return FALSE;
+                   goto error_return;
 
                  vpp = &elf_section_data (s)->local_dynrel;
                  head = (struct elf_dyn_relocs **)vpp;
@@ -1671,7 +1671,7 @@ elf_i386_check_relocs (bfd *abfd,
                  bfd_size_type amt = sizeof *p;
                  p = bfd_alloc (htab->elf.dynobj, amt);
                  if (p == NULL)
-                   return FALSE;
+                   goto error_return;
                  p->next = *head;
                  *head = p;
                  p->sec = sec;
@@ -1689,7 +1689,7 @@ elf_i386_check_relocs (bfd *abfd,
             Reconstruct it for later use during GC.  */
        case R_386_GNU_VTINHERIT:
          if (!bfd_elf_gc_record_vtinherit (abfd, sec, h, rel->r_offset))
-           return FALSE;
+           goto error_return;
          break;
 
          /* This relocation describes which C++ vtable entries are actually
@@ -1698,7 +1698,7 @@ elf_i386_check_relocs (bfd *abfd,
          BFD_ASSERT (h != NULL);
          if (h != NULL
              && !bfd_elf_gc_record_vtentry (abfd, sec, h, rel->r_offset))
-           return FALSE;
+           goto error_return;
          break;
 
        default:
@@ -1706,7 +1706,25 @@ elf_i386_check_relocs (bfd *abfd,
        }
     }
 
+   if (isymbuf != NULL
+       && (unsigned char *) isymbuf != symtab_hdr->contents)
+    {
+      if (!info->keep_memory)
+       free (isymbuf);
+      else
+       {
+         /* Cache the symbols for elf_link_input_bfd.  */
+         symtab_hdr->contents = (unsigned char *) isymbuf;
+       }
+    }
+
   return TRUE;
+
+error_return:
+   if (isymbuf != NULL
+       && (unsigned char *) isymbuf != symtab_hdr->contents)
+     free (isymbuf);
+   return FALSE;
 }
 
 /* Return the section that should be marked against GC for a given
index 617832ab416252b8c11d5a7453cf52d5c886b7b6..581d544013651e857523592ce0e90515f159d89d 100644 (file)
@@ -1094,7 +1094,7 @@ elf64_x86_64_check_relocs (bfd *abfd, struct bfd_link_info *info,
              h = elf64_x86_64_get_local_sym_hash (htab, abfd, rel,
                                                   TRUE);
              if (h == NULL)
-               return FALSE;
+               goto error_return;
              
              /* Fake a STT_GNU_IFUNC symbol.  */
              h->type = STT_GNU_IFUNC;
@@ -1134,7 +1134,7 @@ elf64_x86_64_check_relocs (bfd *abfd, struct bfd_link_info *info,
            case R_X86_64_GOTPCREL:
            case R_X86_64_GOTPCREL64:
              if (!_bfd_elf_create_ifunc_sections (abfd, info))
-               return FALSE;
+               goto error_return;
              break;
            }
 
@@ -1164,7 +1164,7 @@ elf64_x86_64_check_relocs (bfd *abfd, struct bfd_link_info *info,
                      ? h->root.root.string : "a local symbol"),
                     __FUNCTION__);
                  bfd_set_error (bfd_error_bad_value);
-                 return FALSE;
+                 goto error_return;
 
                case R_X86_64_64:
                  h->non_got_ref = 1;
@@ -1178,7 +1178,7 @@ elf64_x86_64_check_relocs (bfd *abfd, struct bfd_link_info *info,
                        (abfd, info, sec, sreloc,
                         &((struct elf64_x86_64_link_hash_entry *) h)->dyn_relocs);
                      if (sreloc == NULL)
-                       return FALSE;
+                       goto error_return;
                    }
                  break;
 
@@ -1201,7 +1201,7 @@ elf64_x86_64_check_relocs (bfd *abfd, struct bfd_link_info *info,
                  if (htab->elf.sgot == NULL
                      && !_bfd_elf_create_got_section (htab->elf.dynobj,
                                                       info))
-                   return FALSE;
+                   goto error_return;
                  break;
                }
 
@@ -1213,7 +1213,7 @@ elf64_x86_64_check_relocs (bfd *abfd, struct bfd_link_info *info,
                                         symtab_hdr, sym_hashes,
                                         &r_type, GOT_UNKNOWN,
                                         rel, rel_end, h))
-       return FALSE;
+       goto error_return;
 
       switch (r_type)
        {
@@ -1230,7 +1230,7 @@ elf64_x86_64_check_relocs (bfd *abfd, struct bfd_link_info *info,
                 x86_64_elf_howto_table[r_type].name,
                 (h) ? h->root.root.string : "a local symbol");
              bfd_set_error (bfd_error_bad_value);
-             return FALSE;
+             goto error_return;
            }
          break;
 
@@ -1290,7 +1290,7 @@ elf64_x86_64_check_relocs (bfd *abfd, struct bfd_link_info *info,
                    local_got_refcounts = ((bfd_signed_vma *)
                                           bfd_zalloc (abfd, size));
                    if (local_got_refcounts == NULL)
-                     return FALSE;
+                     goto error_return;
                    elf_local_got_refcounts (abfd) = local_got_refcounts;
                    elf64_x86_64_local_tlsdesc_gotent (abfd)
                      = (bfd_vma *) (local_got_refcounts + symtab_hdr->sh_info);
@@ -1318,7 +1318,7 @@ elf64_x86_64_check_relocs (bfd *abfd, struct bfd_link_info *info,
                    (*_bfd_error_handler)
                      (_("%B: '%s' accessed both as normal and thread local symbol"),
                       abfd, h ? h->root.root.string : "<local>");
-                   return FALSE;
+                   goto error_return;
                  }
              }
 
@@ -1342,7 +1342,7 @@ elf64_x86_64_check_relocs (bfd *abfd, struct bfd_link_info *info,
                htab->elf.dynobj = abfd;
              if (!_bfd_elf_create_got_section (htab->elf.dynobj,
                                                info))
-               return FALSE;
+               goto error_return;
            }
          break;
 
@@ -1391,7 +1391,7 @@ elf64_x86_64_check_relocs (bfd *abfd, struct bfd_link_info *info,
                 x86_64_elf_howto_table[r_type].name,
                 (h) ? h->root.root.string : "a local symbol");
              bfd_set_error (bfd_error_bad_value);
-             return FALSE;
+             goto error_return;
            }
          /* Fall through.  */
 
@@ -1467,7 +1467,7 @@ elf64_x86_64_check_relocs (bfd *abfd, struct bfd_link_info *info,
                    (sec, htab->elf.dynobj, 3, abfd, /*rela?*/ TRUE);
 
                  if (sreloc == NULL)
-                   return FALSE;
+                   goto error_return;
                }
 
              /* If this is a global symbol, we count the number of
@@ -1487,7 +1487,7 @@ elf64_x86_64_check_relocs (bfd *abfd, struct bfd_link_info *info,
                  s = bfd_section_from_r_symndx (abfd, &htab->sym_sec,
                                                 sec, r_symndx);
                  if (s == NULL)
-                   return FALSE;
+                   goto error_return;
 
                  /* Beware of type punned pointers vs strict aliasing
                     rules.  */
@@ -1503,7 +1503,7 @@ elf64_x86_64_check_relocs (bfd *abfd, struct bfd_link_info *info,
                  p = ((struct elf_dyn_relocs *)
                       bfd_alloc (htab->elf.dynobj, amt));
                  if (p == NULL)
-                   return FALSE;
+                   goto error_return;
                  p->next = *head;
                  *head = p;
                  p->sec = sec;
@@ -1521,7 +1521,7 @@ elf64_x86_64_check_relocs (bfd *abfd, struct bfd_link_info *info,
             Reconstruct it for later use during GC.  */
        case R_X86_64_GNU_VTINHERIT:
          if (!bfd_elf_gc_record_vtinherit (abfd, sec, h, rel->r_offset))
-           return FALSE;
+           goto error_return;
          break;
 
          /* This relocation describes which C++ vtable entries are actually
@@ -1530,7 +1530,7 @@ elf64_x86_64_check_relocs (bfd *abfd, struct bfd_link_info *info,
          BFD_ASSERT (h != NULL);
          if (h != NULL
              && !bfd_elf_gc_record_vtentry (abfd, sec, h, rel->r_addend))
-           return FALSE;
+           goto error_return;
          break;
 
        default:
@@ -1538,7 +1538,25 @@ elf64_x86_64_check_relocs (bfd *abfd, struct bfd_link_info *info,
        }
     }
 
+   if (isymbuf != NULL
+       && (unsigned char *) isymbuf != symtab_hdr->contents)
+    {
+      if (!info->keep_memory)
+       free (isymbuf);
+      else
+       {
+         /* Cache the symbols for elf_link_input_bfd.  */
+         symtab_hdr->contents = (unsigned char *) isymbuf;
+       }
+    }
+
   return TRUE;
+
+error_return:
+   if (isymbuf != NULL
+       && (unsigned char *) isymbuf != symtab_hdr->contents)
+     free (isymbuf);
+   return FALSE;
 }
 
 /* Return the section that should be marked against GC for a given