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

David Mosberger davidm@napali.hpl.hp.com
Fri Mar 1 10:24:00 GMT 2002


>>>>> On Thu, 28 Feb 2002 22:57:57 -0800, Richard Henderson <rth@redhat.com> said:

  Richard> On Thu, Feb 28, 2002 at 10:41:51PM -0800, David Mosberger
  Richard> wrote:
  >> (I don't know what the ${RELOCATING+${INIT_ARRAY_START}} stuff
  >> means in scripttempl/elf.sc; perhaps this does the right thing?)

  Richard> It's sh code.  If RELOCATING is set, then expand
  Richard> INIT_ARRAY_START.  Which you havn't defined to anything, so
  Richard> it's of course empty.

  Richard> You'd want to do something like

  Richard> 	INIT_ARRAY_START="PROVIDE(__init_array_start = .)"
  Richard> ${RELOCATING+${CREATE_SHLIB-${INIT_ARRAY_START}}}

OK, so how about this patch?

With this version, the linker determines whether a DT_*_ARRAY is
needed by search the input bfds for sections with the magic name.
Is there a better way for doing such a check?

	--david

--- bfd/ChangeLog	2002/02/22 20:36:12	1.1363
2002-02-28  David Mosberger  <davidm@hpl.hp.com>

	* elflink.h (size_dynamic_sections): If section named
	".preinit_array" exists, create DT_PREINIT_ARRAY and
	DT_PREINIT_ARRAYSZ entries in dynamic table.  Analogously for
	".init_array" and ".fini_array".
	(elf_bfd_final_link): Handle DT_PREINIT_ARRAYSZ, DT_INIT_ARRAYSZ,
	DT_FINI_ARRAYSZ, DT_PREINIT_ARRAY, DT_INIT_ARRAY, and
	DT_FINI_ARRAY.

--- ld/ChangeLog
2002-02-28  David Mosberger  <davidm@hpl.hp.com>

	* scripttempl/elf.sc (SECTIONS): Add entries for .preinit_array,
	.init_array, and .fini_array.

Index: bfd/elflink.h
===================================================================
RCS file: /cvs/src/src/bfd/elflink.h,v
retrieving revision 1.141
diff -u -r1.141 elflink.h
--- bfd/elflink.h	2002/01/21 10:29:07	1.141
+++ bfd/elflink.h	2002/03/01 17:29:46
@@ -3029,7 +3029,9 @@
      struct bfd_elf_version_tree *verdefs;
 {
   bfd_size_type soname_indx;
-  bfd *dynobj;
+  bfd *dynobj, *sub;
+  asection *o;
+  int need_preinit_array = 0, need_init_array = 0, need_fini_array = 0;
   struct elf_backend_data *bed;
   struct elf_assign_sym_version_info asvinfo;
 
@@ -3200,6 +3202,43 @@
 	    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)
+	      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;
+	}
+
       dynstr = bfd_get_section_by_name (dynobj, ".dynstr");
       /* If .dynstr is excluded from the link, we don't want any of
 	 these tags.  Strictly, we should be checking each section
@@ -5548,6 +5587,31 @@
 		  }
 	      }
 	      break;
+
+	    case DT_PREINIT_ARRAYSZ:
+	      name = ".preinit_array";
+	      goto get_size;
+	    case DT_INIT_ARRAYSZ:
+	      name = ".init_array";
+	      goto get_size;
+	    case DT_FINI_ARRAYSZ:
+	      name = ".fini_array";
+	    get_size:
+	      o = bfd_get_section_by_name (abfd, name);
+	      BFD_ASSERT (o != NULL);
+	      dyn.d_un.d_val = o->_raw_size;
+	      elf_swap_dyn_out (dynobj, &dyn, dyncon);
+	      break;
+
+	    case DT_PREINIT_ARRAY:
+	      name = ".preinit_array";
+	      goto get_vma;
+	    case DT_INIT_ARRAY:
+	      name = ".init_array";
+	      goto get_vma;
+	    case DT_FINI_ARRAY:
+	      name = ".fini_array";
+	      goto get_vma;
 
 	    case DT_HASH:
 	      name = ".hash";
Index: scripttempl/elf.sc
===================================================================
RCS file: /cvs/src/src/ld/scripttempl/elf.sc,v
retrieving revision 1.26
diff -u -r1.26 elf.sc
--- scripttempl/elf.sc	2002/02/12 14:50:08	1.26
+++ scripttempl/elf.sc	2002/03/01 18:23:50
@@ -246,6 +246,18 @@
     ${RELOCATING+${INIT_END}}
   } =${NOP-0}
 
+  ${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} :
   {



More information about the Binutils mailing list