* elflink.h (NAME(bfd_elf,size_dynamic_sections)): Use ELF section
authorAlan Modra <amodra@gmail.com>
Wed, 13 Mar 2002 04:04:49 +0000 (04:04 +0000)
committerAlan Modra <amodra@gmail.com>
Wed, 13 Mar 2002 04:04:49 +0000 (04:04 +0000)
types instead of section names to determine whether init/fini array
dynamic tags are needed.

bfd/ChangeLog
bfd/elflink.h

index 463adc01a8083e72db4844def15aa954faafc0b1..3416865fd690d33f5acbde26966d086a77a74e6a 100644 (file)
@@ -1,5 +1,9 @@
 2002-03-13  Alan Modra  <amodra@bigpond.net.au>
 
+       * elflink.h (NAME(bfd_elf,size_dynamic_sections)): Use ELF section
+       types instead of section names to determine whether init/fini array
+       dynamic tags are needed.
+
        * elflink.h: Formatting fixes.
        (elf_link_output_extsym): Merge undefined and undef weak cases.
 
index 3e8551f9a38a37f064a4360528fbf50510b0142f..438cb4da30d984a089e01738d8c27beb42a7377c 100644 (file)
@@ -3069,6 +3069,9 @@ NAME(bfd_elf,size_dynamic_sections) (output_bfd, soname, rpath,
       struct elf_info_failed eif;
       struct elf_link_hash_entry *h;
       asection *dynstr;
+      bfd *sub;
+      asection *o;
+      int dt_done;
 
       *sinterpptr = bfd_get_section_by_name (dynobj, ".interp");
       BFD_ASSERT (*sinterpptr != NULL || info->shared);
@@ -3200,51 +3203,58 @@ NAME(bfd_elf,size_dynamic_sections) (output_bfd, soname, rpath,
            return false;
        }
 
-      if (bfd_get_section_by_name (output_bfd, ".preinit_array") != NULL)
-       {
-         /* DT_PREINIT_ARRAY is not allowed in shared library.  */
-         if (info->shared)
-           {
-             bfd *sub;
-             asection *o;
-
-             for (sub = info->input_bfds; sub != NULL;
-                  sub = sub->link_next)
-               for (o = sub->sections; o != NULL; o = o->next)
-                 if (elf_section_data (o)->this_hdr.sh_type
-                     == SHT_PREINIT_ARRAY)
-                   {
-                     (*_bfd_error_handler)
-                       (_("%s: .preinit_array section is not allowed in DSO"),
-                         bfd_archive_filename (sub));
-                     break;
-                   }
+      dt_done = 0;
+      for (sub = info->input_bfds; sub != NULL; sub = sub->link_next)
+       for (o = sub->sections; o != NULL; o = o->next)
+         {
+           int tag1, tag2;
 
-             return false;
-           }
+           if (o->output_section == bfd_abs_section_ptr)
+             continue;
 
-         if (!elf_add_dynamic_entry (info, (bfd_vma) DT_PREINIT_ARRAY,
-                                     (bfd_vma) 0)
-             || !elf_add_dynamic_entry (info, (bfd_vma) DT_PREINIT_ARRAYSZ,
-                                        (bfd_vma) 0))
-           return false;
-       }
-      if (bfd_get_section_by_name (output_bfd, ".init_array") != NULL)
-       {
-         if (!elf_add_dynamic_entry (info, (bfd_vma) DT_INIT_ARRAY,
-                                     (bfd_vma) 0)
-             || !elf_add_dynamic_entry (info, (bfd_vma) DT_INIT_ARRAYSZ,
-                                        (bfd_vma) 0))
-           return false;
-       }
-      if (bfd_get_section_by_name (output_bfd, ".fini_array") != NULL)
-       {
-         if (!elf_add_dynamic_entry (info, (bfd_vma) DT_FINI_ARRAY,
-                                     (bfd_vma) 0)
-             || !elf_add_dynamic_entry (info, (bfd_vma) DT_FINI_ARRAYSZ,
-                                        (bfd_vma) 0))
-           return false;
-       }
+           switch (elf_section_data (o)->this_hdr.sh_type)
+             {
+             default:
+               continue;
+
+             case SHT_INIT_ARRAY:
+               if (dt_done & 1)
+                 continue;
+               dt_done |= 1;
+               tag1 = DT_INIT_ARRAY;
+               tag2 = DT_INIT_ARRAYSZ;
+               break;
+
+             case SHT_FINI_ARRAY:
+               if (dt_done & 2)
+                 continue;
+               dt_done |= 2;
+               tag1 = DT_FINI_ARRAY;
+               tag2 = DT_FINI_ARRAYSZ;
+               break;
+
+             case SHT_PREINIT_ARRAY:
+               /* DT_PREINIT_ARRAY is not allowed in a shared library.  */
+               if (info->shared)
+                 {
+                   (*_bfd_error_handler)
+                     (_("%s: .preinit_array section is not allowed in DSO"),
+                      bfd_archive_filename (sub));
+                   bfd_set_error (bfd_error_bad_value);
+                   return false;
+                 }
+               if (dt_done & 4)
+                 continue;
+               dt_done |= 4;
+               tag1 = DT_PREINIT_ARRAY;
+               tag2 = DT_PREINIT_ARRAYSZ;
+               break;
+             }
+
+           if (!elf_add_dynamic_entry (info, (bfd_vma) tag1, (bfd_vma) 0)
+               || !elf_add_dynamic_entry (info, (bfd_vma) tag2, (bfd_vma) 0))
+             return false;
+         }
 
       dynstr = bfd_get_section_by_name (dynobj, ".dynstr");
       /* If .dynstr is excluded from the link, we don't want any of