This is the mail archive of the binutils@sourceware.org mailing list for the binutils project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

RFC: PR ld/18379: Add the --fini-array-register option to ld


To support .fini_array, linker always links in the .fini_array handler
even if it isn't used.  This patch adds the  --fini-array-register
option to ld to specify the function to call to register the .fini_array
handler for the static executable.  If there is a non-empty .fini_array
input section, it changes the weak reference to the function for
registering the .fini_array handler to non-weak so that it will be linked
in.  Any comments?

Thanks.


H.J.
---
diff --git a/bfd/elflink.c b/bfd/elflink.c
index 6efe1e4..888c5e5 100644
--- a/bfd/elflink.c
+++ b/bfd/elflink.c
@@ -3458,6 +3458,22 @@ elf_link_add_object_symbols (bfd *abfd, struct bfd_link_info *info)
 	      s->flags |= SEC_EXCLUDE;
 	    }
 	}
+      else if (info->fini_array_register != NULL
+	       && info->executable
+	       && s->size > 0
+	       && CONST_STRNEQ (name, ".fini_array"))
+	{
+	  struct elf_link_hash_entry *h;
+
+	  /* Change the weak reference to the function for registering
+	     the .fini_array handler to non-weak so that it will be
+	     linked in.  */
+	  h = elf_link_hash_lookup (htab, info->fini_array_register,
+				    FALSE, FALSE, FALSE);
+	  if (h != NULL
+	      && h->root.type == bfd_link_hash_undefweak)
+	    h->root.type = bfd_link_hash_undefined;
+	}
     }
 
   just_syms = ((s = abfd->sections) != NULL
diff --git a/include/bfdlink.h b/include/bfdlink.h
index 3989c60..07b24db 100644
--- a/include/bfdlink.h
+++ b/include/bfdlink.h
@@ -509,6 +509,10 @@ struct bfd_link_info
      unloaded.  */
   const char *fini_function;
 
+  /* The function to call to register the .fini_array handler for the
+     static executable.  */
+  const char *fini_array_register;
+
   /* Number of relaxation passes.  Usually only one relaxation pass
      is needed.  But a backend can have as many relaxation passes as
      necessary.  During bfd_relax_section call, it is set to the
diff --git a/ld/ldlex.h b/ld/ldlex.h
index f174c28..9474d84 100644
--- a/ld/ldlex.h
+++ b/ld/ldlex.h
@@ -107,6 +107,7 @@ enum option_values
   OPTION_NO_UNDEFINED,
   OPTION_INIT,
   OPTION_FINI,
+  OPTION_FINI_ARRAY_REGISTER,
   OPTION_SECTION_START,
   OPTION_UNIQUE,
   OPTION_TARGET_HELP,
diff --git a/ld/lexsup.c b/ld/lexsup.c
index b618241..a5dd62c 100644
--- a/ld/lexsup.c
+++ b/ld/lexsup.c
@@ -313,6 +313,8 @@ static const struct ld_option ld_options[] =
     TWO_DASHES },
   { {"fini", required_argument, NULL, OPTION_FINI},
     '\0', N_("SYMBOL"), N_("Call SYMBOL at unload-time"), ONE_DASH },
+  { {"fini-array-register", required_argument, NULL, OPTION_FINI_ARRAY_REGISTER},
+    '\0', N_("SYMBOL"), N_("Call SYMBOL to register .fini_array handler"), ONE_DASH },
   { {"force-exe-suffix", no_argument, NULL, OPTION_FORCE_EXE_SUFFIX},
     '\0', NULL, N_("Force generation of file with .exe suffix"), TWO_DASHES},
   { {"gc-sections", no_argument, NULL, OPTION_GC_SECTIONS},
@@ -1456,6 +1458,10 @@ parse_args (unsigned argc, char **argv)
 	  link_info.fini_function = optarg;
 	  break;
 
+	case OPTION_FINI_ARRAY_REGISTER:
+	  link_info.fini_array_register = optarg;
+	  break;
+
 	case OPTION_REDUCE_MEMORY_OVERHEADS:
 	  link_info.reduce_memory_overheads = TRUE;
 	  if (config.hash_table_size == 0)


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]