This is the mail archive of the
binutils@sourceware.org
mailing list for the binutils project.
RFC: PR ld/18379: Add the --fini-array-register option to ld
- From: "H.J. Lu" <hongjiu dot lu at intel dot com>
- To: binutils at sourceware dot org
- Date: Tue, 5 May 2015 14:18:26 -0700
- Subject: RFC: PR ld/18379: Add the --fini-array-register option to ld
- Authentication-results: sourceware.org; auth=none
- Reply-to: "H.J. Lu" <hjl dot tools at gmail dot com>
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)