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

H . J . Lu hjl@lucon.org
Sat Mar 2 10:59:00 GMT 2002


On Sat, Mar 02, 2002 at 09:19:16AM -0800, David Mosberger wrote:
> >>>>> On Sat, 2 Mar 2002 20:49:31 +1030, Alan Modra <amodra@bigpond.net.au> said:
> 
>   Alan> On Sat, Mar 02, 2002 at 12:36:45AM -0800, H . J . Lu wrote:
>   >>  .init_array, .fini_array and .preinit_array are new special
>   >> sections.  We need to make sure their types and attributes are
>   >> correct. Here is a patch.
> 
>   Alan> I like this, but there is a mistake in the following
> 
>   >> @@ -3370,18 +3371,27 @@ NAME(bfd_elf,size_dynamic_sections) (out
>   >> return false; }
>   >> 
>   >> - 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... */
>   >> -
>   >> - if (strcmp (bfd_section_name (sub, o), ".preinit_array") == 0)
>   >> + for (sub = info->input_bfds; sub != NULL && initfini_array !=
>   >> 3; + sub = sub->link_next) + for (o = sub->sections; o != NULL &&
>   >> initfini_array != 3; + o = o->next) + switch (elf_section_data
>   >> (o->output_section)->this_hdr.sh_type) + { + case
>   >> SHT_PREINIT_ARRAY: need_preinit_array = 1; - if (strcmp
>   >> (bfd_section_name (sub, o), ".init_array") == 0) +
>   >> initfini_array++;
> 
>   Alan> Presumably, initfini_array is trying to cut short the section
>   Alan> search after finding one of each of the section types.  I
>   Alan> can't see anything in the ELF spec that precludes having, say,
>   Alan> three SHT_PREINIT_ARRAY input sections.  Best get rid of
>   Alan> initfini_array entirely.
> 
> The loop really only needs to determine whether any _input_ sections
> contain the preinit/init/fini arrays.  You could use a bitmask and
> stop the search as soon as all three array sections have occurred at
> least once.
> 
> I considered doing that but opted not to do so for clarity and because
> I wasn't sure how often preinit arrays will be used: if it turns out
> that most executables do not use preinit arrays, then the optimization
> won't be very useful.

The problem is you are searching all input files. It doesn't matter
they are used or not.

> 
>   Alan> The other thing is that you'll need to extend your patch a
>   Alan> little to handle these section types in bfd_section_from_shdr.
> 
> Also, note that elfxx-ia64.c already has code to set the section
> types.  It's good if this can be moved to elf.c, but there is no point
> in keeping two copies of this code.
> 
> 	--david


Here is a new patch. I made a few changes. I use

elf_section_data (o)->this_hdr.sh_type 

since 

elf_section_data (o->output_section)

is 0 when it is called. Also, those new sections should be in the
data segment. And I fixed a few typos.

BTW, should we allow both .init/.fini and the array sections. If both
exist, how should ld.so treat them?


H.J.
---
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)): Check the
	section types instead of names for .init_array, .fini_array and
	.preinit_array.

	* 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.

--- binutils/bfd/elf.c.array	Tue Feb 19 15:17:40 2002
+++ binutils/bfd/elf.c	Sat Mar  2 09:55:43 2002
@@ -1564,6 +1564,9 @@ bfd_section_from_shdr (abfd, shindex)
     case SHT_NOBITS:	/* .bss section.  */
     case SHT_HASH:	/* .hash section.  */
     case SHT_NOTE:	/* .note section.  */
+    case SHT_INIT_ARRAY:	/* .init_array section.  */
+    case SHT_FINI_ARRAY:	/* .fini_array section.  */
+    case SHT_PREINIT_ARRAY:	/* .preinit_array section.  */
       return _bfd_elf_make_section_from_shdr (abfd, hdr, name);
 
     case SHT_SYMTAB:		/* A symbol table */
@@ -2178,6 +2181,12 @@ elf_fake_sections (abfd, asect, failedpt
       this_hdr->sh_type = SHT_REL;
       this_hdr->sh_entsize = bed->s->sizeof_rel;
     }
+  else if (strcmp (asect->name, ".init_array") == 0)
+    this_hdr->sh_type = SHT_INIT_ARRAY;
+  else if (strcmp (asect->name, ".fini_array") == 0)
+    this_hdr->sh_type = SHT_FINI_ARRAY;
+  else if (strcmp (asect->name, ".preinit_array") == 0)
+    this_hdr->sh_type = SHT_PREINIT_ARRAY;
   else if (strncmp (asect->name, ".note", 5) == 0)
     this_hdr->sh_type = SHT_NOTE;
   else if (strncmp (asect->name, ".stab", 5) == 0
--- binutils/bfd/elflink.h.array	Fri Mar  1 23:44:22 2002
+++ binutils/bfd/elflink.h	Sat Mar  2 10:48:17 2002
@@ -3199,7 +3199,11 @@ NAME(bfd_elf,size_dynamic_sections) (out
   bfd_size_type soname_indx;
   bfd *dynobj, *sub;
   asection *o;
-  int need_preinit_array = 0, need_init_array = 0, need_fini_array = 0;
+#define PREINIT_ARRAY_MASK	1
+#define INIT_ARRAY_MASK		2
+#define FINI_ARRAY_MASK		4
+#define ALL_ARRAY_MASK		7
+  int dt_array = 0;
   struct elf_backend_data *bed;
   struct elf_assign_sym_version_info asvinfo;
 
@@ -3373,39 +3377,50 @@ NAME(bfd_elf,size_dynamic_sections) (out
       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 array = 0, arraysz = 0;
 
-	    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 (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;
+	    switch (elf_section_data (o)->this_hdr.sh_type)
+	      {
+	      case SHT_PREINIT_ARRAY:
+		if ((dt_array & PREINIT_ARRAY_MASK) == 0)
+		  {
+		    array = DT_PREINIT_ARRAY;
+		    arraysz = DT_PREINIT_ARRAYSZ;
+		    dt_array |= PREINIT_ARRAY_MASK;
+		  }
+		break;
+	      case SHT_INIT_ARRAY:
+		if ((dt_array & INIT_ARRAY_MASK) == 0)
+		  {
+		    array = DT_INIT_ARRAY;
+		    arraysz = DT_INIT_ARRAYSZ;
+		    dt_array |= INIT_ARRAY_MASK;
+		  }
+		break;
+	      case SHT_FINI_ARRAY:
+		if ((dt_array & FINI_ARRAY_MASK) == 0)
+		  {
+		    array = DT_FINI_ARRAY;
+		    arraysz = DT_FINI_ARRAYSZ;
+		    dt_array |= FINI_ARRAY_MASK;
+		  }
+		break;
+	      default:
+	      }
+
+	    if (array)
+	      {
+		if (!elf_add_dynamic_entry (info, (bfd_vma) array,
+					    (bfd_vma) 0)
+		    || !elf_add_dynamic_entry (info, (bfd_vma) arraysz,
+					       (bfd_vma) 0))
+		  return false;
+	      }
+
+	    if ((dt_array & ALL_ARRAY_MASK) == ALL_ARRAY_MASK)
+	      goto array_done;
 	}
+array_done:
 
       dynstr = bfd_get_section_by_name (dynobj, ".dynstr");
       /* If .dynstr is excluded from the link, we don't want any of
--- binutils/bfd/elfxx-ia64.c.array	Tue Feb 19 15:18:24 2002
+++ binutils/bfd/elfxx-ia64.c	Sat Mar  2 10:21:20 2002
@@ -1016,9 +1016,6 @@ elfNN_ia64_section_from_shdr (abfd, hdr,
   switch (hdr->sh_type)
     {
     case SHT_IA_64_UNWIND:
-    case SHT_INIT_ARRAY:
-    case SHT_FINI_ARRAY:
-    case SHT_PREINIT_ARRAY:
     case SHT_IA_64_HP_OPT_ANOT:
       break;
 
@@ -1076,12 +1073,6 @@ elfNN_ia64_fake_sections (abfd, hdr, sec
     }
   else if (strcmp (name, ELF_STRING_ia64_archext) == 0)
     hdr->sh_type = SHT_IA_64_EXT;
-  else if (strcmp (name, ".init_array") == 0)
-    hdr->sh_type = SHT_INIT_ARRAY;
-  else if (strcmp (name, ".fini_array") == 0)
-    hdr->sh_type = SHT_FINI_ARRAY;
-  else if (strcmp (name, ".preinit_array") == 0)
-    hdr->sh_type = SHT_PREINIT_ARRAY;
   else if (strcmp (name, ".HP.opt_annot") == 0)
     hdr->sh_type = SHT_IA_64_HP_OPT_ANOT;
   else if (strcmp (name, ".reloc") == 0)
--- binutils/gas/config/obj-elf.c.array	Fri Mar  1 23:44:32 2002
+++ binutils/gas/config/obj-elf.c	Sat Mar  2 00:10:52 2002
@@ -595,6 +595,9 @@ static struct special_section const spec
   { ".rodata",	SHT_PROGBITS,	SHF_ALLOC			},
   { ".rodata1",	SHT_PROGBITS,	SHF_ALLOC			},
   { ".text",	SHT_PROGBITS,	SHF_ALLOC + SHF_EXECINSTR	},
+  { ".init_array",SHT_INIT_ARRAY, SHF_ALLOC + SHF_WRITE         }, 
+  { ".fini_array",SHT_FINI_ARRAY, SHF_ALLOC + SHF_WRITE         },
+  { ".preinit_array",SHT_PREINIT_ARRAY, SHF_ALLOC + SHF_WRITE   }, 
 
 #ifdef ELF_TC_SPECIAL_SECTIONS
   ELF_TC_SPECIAL_SECTIONS
--- binutils/gas/config/tc-ia64.h.array	Tue Jan 15 11:30:50 2002
+++ binutils/gas/config/tc-ia64.h	Sat Mar  2 00:10:52 2002
@@ -124,8 +124,6 @@ extern void ia64_after_parse_args PARAMS
 #define WORKING_DOT_WORD	/* don't do broken word processing for now */
 
 #define ELF_TC_SPECIAL_SECTIONS						   \
-{ ".init_array",SHT_INIT_ARRAY,	SHF_ALLOC + SHF_WRITE                   }, \
-{ ".fini_array",SHT_FINI_ARRAY,	SHF_ALLOC + SHF_WRITE                   }, \
 { ".sbss",	SHT_NOBITS,	SHF_ALLOC + SHF_WRITE + SHF_IA_64_SHORT }, \
 { ".sdata",	SHT_PROGBITS,	SHF_ALLOC + SHF_WRITE + SHF_IA_64_SHORT },
 
--- binutils/ld/scripttempl/elf.sc.array	Fri Mar  1 23:45:33 2002
+++ binutils/ld/scripttempl/elf.sc	Sat Mar  2 10:43:32 2002
@@ -246,23 +246,6 @@ cat <<EOF
     ${RELOCATING+${INIT_END}}
   } =${NOP-0}
 
-  /* Ensure the __preinit_array_start label is properly aligned.  We
-     could instead move the label definition inside the section, but
-     the linker would then create the section even if it turns out to
-     be empty, which isn't pretty.  */
-  ${RELOCATING+. = ALIGN(${ALIGNMENT})}
-  ${RELOCATING+${CREATE_SHLIB-PROVIDE (__preinit_array_start = .);}}
-  .preinit_array   ${RELOCATING-0} : { *(.preinit_array) }
-  ${RELOCATING+${CREATE_SHLIB-PROVIDE (__preinit_array_end = .);}}
-
-  ${RELOCATING+${CREATE_SHLIB-PROVIDE (__init_array_start = .)}};
-  .init_array   ${RELOCATING-0} : { *(.init_array) }
-  ${RELOCATING+${CREATE_SHLIB-PROVIDE (__init_array_end = .);}}
-
-  ${RELOCATING+${CREATE_SHLIB-PROVIDE (__fini_array_start = .);}}
-  .fini_array   ${RELOCATING-0} : { *(.fini_array) }
-  ${RELOCATING+${CREATE_SHLIB-PROVIDE (__fini_array_end = .);}}
-
   ${DATA_PLT-${BSS_PLT-${PLT}}}
   .text         ${RELOCATING-0} :
   {
@@ -293,6 +276,23 @@ cat <<EOF
   ${CREATE_SHLIB-${RELOCATING+. = ${DATA_ADDR-${DATA_SEGMENT_ALIGN}};}}
   ${CREATE_SHLIB+${RELOCATING+. = ${SHLIB_DATA_ADDR-${DATA_SEGMENT_ALIGN}};}}
 
+  /* Ensure the __preinit_array_start label is properly aligned.  We
+     could instead move the label definition inside the section, but
+     the linker would then create the section even if it turns out to
+     be empty, which isn't pretty.  */
+  ${RELOCATING+. = ALIGN(${ALIGNMENT});}
+  ${RELOCATING+${CREATE_SHLIB-PROVIDE (__preinit_array_start = .);}}
+  .preinit_array   ${RELOCATING-0} : { *(.preinit_array) }
+  ${RELOCATING+${CREATE_SHLIB-PROVIDE (__preinit_array_end = .);}}
+
+  ${RELOCATING+${CREATE_SHLIB-PROVIDE (__init_array_start = .);}}
+  .init_array   ${RELOCATING-0} : { *(.init_array) }
+  ${RELOCATING+${CREATE_SHLIB-PROVIDE (__init_array_end = .);}}
+
+  ${RELOCATING+${CREATE_SHLIB-PROVIDE (__fini_array_start = .);}}
+  .fini_array   ${RELOCATING-0} : { *(.fini_array) }
+  ${RELOCATING+${CREATE_SHLIB-PROVIDE (__fini_array_end = .);}}
+
   .data         ${RELOCATING-0} :
   {
     ${RELOCATING+${DATA_START_SYMBOLS}}



More information about the Binutils mailing list