This is the mail archive of the
binutils@sourceware.org
mailing list for the binutils project.
Re: [5/6][PATCH] Perform second link stage and ignore now-obsolete linker -pass-through= option.
On 26/02/2011 00:46, Dave Korn wrote:
I started forgetting to add the patches about half-way through there...
>From 8fb73a8834169d39ed90c5dcf25a1cdf62e95e09 Mon Sep 17 00:00:00 2001
From: Dave Korn <dave.korn.cygwin@gmail.com>
Date: Sun, 20 Feb 2011 00:38:54 +0000
Subject: [PATCH] Perform second link stage and ignore now-obsolete linker -pass-through= option.
ld/ChangeLog:
2011-02-20 Dave Korn <...
PR ld/12365
* ldcref.c (cref_hash_table_free): New function.
* ld.h (cref_hash_table_free): Add prototype.
* ldlang.c (lang_gc_sections): Dont de-exclude claimed file sections.
(set_exclude): New function.
(reopen_inputs): Likewise. Walk list of input objects, excluding
claimed (IR-only) files and archive members, then re-walk list, closing
and re-opening and re-adding the symbols from objects and libs.
(lang_process): After opening plugin-supplied objects and scanning
their library dependencies, tear down existing link, cref and
already-linked-section hashes, erase link_info input bfds list, finally
call reopen_inputs.
* plugin.c (plugin_opt_plugin_arg): Discard any instances of the
now-obsolete "-pass-through=" option if found.
---
ld/ld.h | 1 +
ld/ldcref.c | 18 +++++++++++
ld/ldlang.c | 93 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
ld/plugin.c | 3 ++
4 files changed, 115 insertions(+), 0 deletions(-)
diff --git a/ld/ld.h b/ld/ld.h
index 564cb73..dfa3f2e 100644
--- a/ld/ld.h
+++ b/ld/ld.h
@@ -327,6 +327,7 @@ extern int parsing_defsym;
extern int yyparse (void);
extern void add_cref (const char *, bfd *, asection *, bfd_vma);
+extern void cref_hash_table_free (void);
extern bfd_boolean handle_asneeded_cref (bfd *, enum notice_asneeded_action);
extern void output_cref (FILE *);
extern void check_nocrossrefs (void);
diff --git a/ld/ldcref.c b/ld/ldcref.c
index 2f6a46c..889b38a 100644
--- a/ld/ldcref.c
+++ b/ld/ldcref.c
@@ -198,6 +198,24 @@ add_cref (const char *name,
r->def = TRUE;
}
+/* Free the cref hash table. */
+
+void
+cref_hash_table_free (void)
+{
+ if (cref_initialized)
+ {
+ bfd_hash_table_free (&cref_table.root);
+ cref_initialized = FALSE;
+ cref_symcount = 0;
+ old_table = NULL;
+ old_size = 0;
+ old_count = 0;
+ old_symcount = 0;
+ alloc_mark = NULL;
+ }
+}
+
/* Called before loading an as-needed library to take a snapshot of
the cref hash table, and after we have loaded or found that the
library was not needed. */
diff --git a/ld/ldlang.c b/ld/ldlang.c
index 7a1753d..7330dc0 100644
--- a/ld/ldlang.c
+++ b/ld/ldlang.c
@@ -6269,6 +6269,10 @@ lang_gc_sections (void)
LANG_FOR_EACH_INPUT_STATEMENT (f)
{
asection *sec;
+#ifdef ENABLE_PLUGINS
+ if (f->claimed)
+ continue;
+#endif /* ENABLE_PLUGINS */
for (sec = f->the_bfd->sections; sec != NULL; sec = sec->next)
if ((sec->flags & SEC_DEBUGGING) == 0)
sec->flags &= ~SEC_EXCLUDE;
@@ -6442,6 +6446,69 @@ find_replacements_insert_point (void)
insert point. */
return lastobject;
}
+
+/* Mapped over sections of claimed IR BFDs to exclude them from the
+ final link. */
+
+static void
+set_exclude (bfd *abfd, asection *sect, void *obj ATTRIBUTE_UNUSED)
+{
+ bfd_set_section_flags (abfd,
+ sect,
+ SEC_EXCLUDE | bfd_get_section_flags (abfd, sect));
+ sect->output_section = NULL;
+}
+
+/* This runs two passes over the inputs. First we exclude any IR
+ BFDs and archive members from the link; then we re-run it by
+ re-opening all the object files and archives and re-adding
+ their symbols to the fresh linker hash table. */
+
+static void
+reopen_inputs (void)
+{
+ lang_input_statement_type *stmt;
+
+ /* Exclude dummy IR files and archive members. */
+ for (stmt = &file_chain.head->input_statement;
+ stmt != NULL;
+ stmt = &stmt->next->input_statement)
+ {
+ if (stmt->claimed || (stmt->the_bfd && bfd_my_archive (stmt->the_bfd)))
+ {
+ bfd_map_over_sections (stmt->the_bfd, set_exclude, 0);
+ stmt->claimed = TRUE;
+ }
+ }
+
+ /* Re-open real objects and libs, recalculating link as we go. */
+ for (stmt = &input_file_chain.head->input_statement;
+ stmt != NULL;
+ stmt = &stmt->next_real_file->input_statement)
+ {
+ if (!stmt->claimed && stmt->the_bfd && !bfd_my_archive (stmt->the_bfd))
+ {
+ bfd *oldbfd = stmt->the_bfd;
+ stmt->the_bfd = NULL;
+ ldfile_open_file (stmt);
+ bfd_check_format (stmt->the_bfd, bfd_get_format (oldbfd));
+ if (bfd_get_format (stmt->the_bfd) != bfd_archive)
+ {
+ *link_info.input_bfds_tail = stmt->the_bfd;
+ stmt->the_bfd->link_next = NULL;
+ link_info.input_bfds_tail = &stmt->the_bfd->link_next;
+ }
+ stmt->the_bfd->usrdata = stmt;
+ bfd_set_gp_size (stmt->the_bfd, g_switch_value);
+ bfd_map_over_sections (stmt->the_bfd, section_already_linked, stmt);
+ bfd_link_add_symbols (stmt->the_bfd, &link_info);
+ /* We need to hold archive BFDs open while we still have statements
+ indicating them; plain object files we are finished with now. */
+ if (bfd_get_format (oldbfd) == bfd_object)
+ bfd_close (oldbfd);
+ }
+ }
+}
#endif /* ENABLE_PLUGINS */
void
@@ -6518,6 +6585,32 @@ lang_process (void)
else
lang_list_insert_after (&file_chain, &files, &file_chain.head);
}
+
+ /* Free the old already linked table and create a new one. */
+ bfd_section_already_linked_table_free ();
+ if (!bfd_section_already_linked_table_init ())
+ einfo (_("%P%F: Failed to create hash table\n"));
+
+ /* Free the old hash table and create a new one. */
+ bfd_link_hash_table_free (link_info.output_bfd,
+ link_info.hash);
+ link_info.hash
+ = bfd_link_hash_table_create (link_info.output_bfd);
+ if (link_info.hash == NULL)
+ einfo (_("%P%F: can not create hash table: %E\n"));
+
+ /* Re-add to the hash table all undefineds on the command line. */
+ lang_place_undefineds ();
+
+ /* Free the old cref hash table. */
+ cref_hash_table_free ();
+
+ /* And relink the input bfds list. */
+ link_info.input_bfds = NULL;
+ link_info.input_bfds_tail = &link_info.input_bfds;
+
+ /* Now run round the input objects re-adding symbols. */
+ reopen_inputs ();
}
#endif /* ENABLE_PLUGINS */
diff --git a/ld/plugin.c b/ld/plugin.c
index c1672f6..db3ad07 100644
--- a/ld/plugin.c
+++ b/ld/plugin.c
@@ -207,6 +207,9 @@ plugin_opt_plugin_arg (const char *arg)
if (!last_plugin)
return set_plugin_error (_("<no plugin>"));
+ if (CONST_STRNEQ (arg, "-pass-through="))
+ return 0;
+
newarg = xmalloc (sizeof *newarg);
newarg->arg = arg;
newarg->next = NULL;