Allow symbol and label names to be enclosed in double quotes.
[binutils-gdb.git] / bfd / xcofflink.c
index f6c7fe6fa303d0a18653885d07e65e988773f2ba..75977501a89290f71a48254524a19ac608f314d0 100644 (file)
@@ -1,5 +1,5 @@
 /* POWER/PowerPC XCOFF linker support.
-   Copyright (C) 1995-2014 Free Software Foundation, Inc.
+   Copyright (C) 1995-2015 Free Software Foundation, Inc.
    Written by Ian Lance Taylor <ian@cygnus.com>, Cygnus Support.
 
    This file is part of BFD, the Binary File Descriptor library.
@@ -573,14 +573,17 @@ xcoff_link_hash_newfunc (struct bfd_hash_entry *entry,
 
 /* Destroy an XCOFF link hash table.  */
 
-void
-_bfd_xcoff_bfd_link_hash_table_free (struct bfd_link_hash_table *hash)
+static void
+_bfd_xcoff_bfd_link_hash_table_free (bfd *obfd)
 {
-  struct xcoff_link_hash_table *ret = (struct xcoff_link_hash_table *) hash;
+  struct xcoff_link_hash_table *ret;
 
-  _bfd_stringtab_free (ret->debug_strtab);
-  bfd_hash_table_free (&ret->root.table);
-  free (ret);
+  ret = (struct xcoff_link_hash_table *) obfd->link.hash;
+  if (ret->archive_info)
+    htab_delete (ret->archive_info);
+  if (ret->debug_strtab)
+    _bfd_stringtab_free (ret->debug_strtab);
+  _bfd_generic_link_hash_table_free (obfd);
 }
 
 /* Create an XCOFF link hash table.  */
@@ -604,6 +607,12 @@ _bfd_xcoff_bfd_link_hash_table_create (bfd *abfd)
   ret->debug_strtab = _bfd_xcoff_stringtab_init ();
   ret->archive_info = htab_create (37, xcoff_archive_info_hash,
                                   xcoff_archive_info_eq, NULL);
+  if (!ret->debug_strtab || !ret->archive_info)
+    {
+      _bfd_xcoff_bfd_link_hash_table_free (abfd);
+      return NULL;
+    }
+  ret->root.hash_table_free = _bfd_xcoff_bfd_link_hash_table_free;
 
   /* The linker will always generate a full a.out header.  We need to
      record that fact now, before the sizeof_headers routine could be
@@ -1041,7 +1050,7 @@ xcoff_link_create_extra_sections (bfd * abfd, struct bfd_link_info *info)
         won't work if we're producing an XCOFF output file with no
         XCOFF input files.  FIXME.  */
 
-      if (!info->relocatable
+      if (!bfd_link_relocatable (info)
          && xcoff_hash_table (info)->loader_section == NULL)
        {
          asection *lsec;
@@ -2375,6 +2384,8 @@ xcoff_link_check_ar_symbols (bfd *abfd,
 static bfd_boolean
 xcoff_link_check_archive_element (bfd *abfd,
                                  struct bfd_link_info *info,
+                                 struct bfd_link_hash_entry *h ATTRIBUTE_UNUSED,
+                                 const char *name ATTRIBUTE_UNUSED,
                                  bfd_boolean *pneeded)
 {
   bfd_boolean keep_syms_p;
@@ -2454,7 +2465,7 @@ _bfd_xcoff_bfd_link_add_symbols (bfd *abfd, struct bfd_link_info *info)
                bfd_boolean needed;
 
                if (! xcoff_link_check_archive_element (member, info,
-                                                       &needed))
+                                                       NULL, NULL, &needed))
                  return FALSE;
                if (needed)
                  member->archive_pass = -1;
@@ -2689,7 +2700,7 @@ xcoff_mark_symbol (struct bfd_link_info *info, struct xcoff_link_hash_entry *h)
 
   /* If we're marking an undefined symbol, try find some way of
      defining it.  */
-  if (!info->relocatable
+  if (!bfd_link_relocatable (info)
       && (h->flags & XCOFF_IMPORT) == 0
       && (h->flags & XCOFF_DEF_REGULAR) == 0
       && (h->root.type == bfd_link_hash_undefined
@@ -3703,7 +3714,7 @@ bfd_xcoff_size_dynamic_sections (bfd *output_bfd,
     }
 
   /* Garbage collect unused sections.  */
-  if (info->relocatable || !gc)
+  if (bfd_link_relocatable (info) || !gc)
     {
       gc = FALSE;
       xcoff_hash_table (info)->gc = FALSE;
@@ -4483,7 +4494,10 @@ xcoff_link_input_bfd (struct xcoff_final_link_info *flinfo,
                          if (strings == NULL)
                            return FALSE;
                        }
-                     filename = strings + aux.x_file.x_n.x_offset;
+                     if ((bfd_size_type) aux.x_file.x_n.x_offset >= obj_coff_strings_len (input_bfd))
+                       filename = _("<corrupt>");
+                     else
+                       filename = strings + aux.x_file.x_n.x_offset;
                      indx = _bfd_stringtab_add (flinfo->strtab, filename,
                                                 hash, copy);
                      if (indx == (bfd_size_type) -1)
@@ -5724,7 +5738,7 @@ xcoff_reloc_link_order (bfd *output_bfd,
 
       size = bfd_get_reloc_size (howto);
       buf = bfd_zmalloc (size);
-      if (buf == NULL)
+      if (buf == NULL && size != 0)
        return FALSE;
 
       rstat = _bfd_relocate_contents (howto, output_bfd, addend, buf);
@@ -5816,7 +5830,7 @@ _bfd_xcoff_bfd_final_link (bfd *abfd, struct bfd_link_info *info)
   file_ptr pos;
   bfd_size_type amt;
 
-  if (info->shared)
+  if (bfd_link_pic (info))
     abfd->flags |= DYNAMIC;
 
   symesz = bfd_coff_symesz (abfd);