[David Mosberger <davidm@hpl.hp.com>] problem with unwind info for .init/.fini sections

Alan Modra amodra@bigpond.net.au
Mon Mar 4 03:06:00 GMT 2002


On Sun, Mar 03, 2002 at 12:32:08AM -0800, H . J . Lu wrote:
> 2002-03-02  H.J. Lu <hjl@gnu.org>
> 
> 	* elf.c (bfd_section_from_shdr): Handle special sections,
> 	.init_array, .fini_array and .preinit_array.
> 	(elf_fake_sections): Likewise.
> 
> 	* elflink.h (NAME(bfd_elf,size_dynamic_sections)): Create the
> 	DT entry only if the section is in output for .init_array,
> 	.fini_array and .preinit_array. Complain about .preinit_array
> 	section in DSO.
> 
> 	* elfxx-ia64.c (elfNN_ia64_section_from_shdr): Remove
> 	SHT_INIT_ARRAY, SHT_FINI_ARRAY and SHT_PREINIT_ARRAY.
> 	(elfNN_ia64_fake_sections): Remove .init_array, .fini_array and
> 	.preinit_array.
> 
> 2002-03-02  H.J. Lu <hjl@gnu.org>
> 
> 	* config/obj-elf.c (special_section): Add .init_array,
> 	.fini_array and .preinit_array.
> 
> 	* config/tc-ia64.h (ELF_TC_SPECIAL_SECTIONS): Remove
> 	.init_array and .fini_array.
> 
> 2002-03-02  H.J. Lu <hjl@gnu.org>
> 
> 	* scripttempl/elf.sc: Fix a few typos. Put .preinit_array,
> 	.init_array and .fini_array in the data segment. Don't provide
> 	__preinit_array_start/__preinit_array_end labels for shared
> 	library.

This is OK to commit, although you might like to use the following
elflink.h patch instead.  It's based on one of your earlier patches,
and has the advantage of being immune to people using custom linker
scripts that define symbols in the .init_array, .fini_array or
.preinit_array output sections.

Index: bfd/elflink.h
===================================================================
RCS file: /cvs/src/src/bfd/elflink.h,v
retrieving revision 1.143
diff -u -p -r1.143 elflink.h
--- elflink.h	2002/03/02 01:24:50	1.143
+++ elflink.h	2002/03/04 10:47:08
@@ -3029,9 +3029,7 @@ NAME(bfd_elf,size_dynamic_sections) (out
      struct bfd_elf_version_tree *verdefs;
 {
   bfd_size_type soname_indx;
-  bfd *dynobj, *sub;
-  asection *o;
-  int need_preinit_array = 0, need_init_array = 0, need_fini_array = 0;
+  bfd *dynobj;
   struct elf_backend_data *bed;
   struct elf_assign_sym_version_info asvinfo;
 
@@ -3071,6 +3069,9 @@ NAME(bfd_elf,size_dynamic_sections) (out
       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);
@@ -3202,42 +3203,57 @@ NAME(bfd_elf,size_dynamic_sections) (out
 	    return false;
 	}
 
+      dt_done = 0;
       for (sub = info->input_bfds; sub != NULL; sub = sub->link_next)
 	for (o = sub->sections; o != NULL; o = o->next)
 	  {
-	    /* yuck, more matching by name... */
+	    int tag1, tag2;
 
-	    if (strcmp (bfd_section_name (sub, o), ".preinit_array") == 0)
-	      need_preinit_array = 1;
-	    if (strcmp (bfd_section_name (sub, o), ".init_array") == 0)
-	      need_init_array = 1;
-	    if (strcmp (bfd_section_name (sub, o), ".fini_array") == 0)
-	      need_fini_array = 1;
+	    if (o->output_section == bfd_abs_section_ptr)
+	      continue;
+
+	    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));
+		    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;
 	  }
-      if (need_preinit_array)
-	{
-	  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 (need_init_array)
-	{
-	  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 (need_fini_array)
-	{
-	  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;
-	}
 
       dynstr = bfd_get_section_by_name (dynobj, ".dynstr");
       /* If .dynstr is excluded from the link, we don't want any of

-- 
Alan Modra
IBM OzLabs - Linux Technology Centre



More information about the Binutils mailing list