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]

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;

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