This is the mail archive of the
binutils@sourceware.org
mailing list for the binutils project.
Re: PATCH: 2 stage BFD linker for LTO plugin
- From: Alan Modra <amodra at gmail dot com>
- To: binutils at sourceware dot org
- Date: Fri, 15 Apr 2011 13:50:15 +0930
- Subject: Re: PATCH: 2 stage BFD linker for LTO plugin
- References: <AANLkTin+Ag09_9DbWdJ71WOg+bqcBGepcThkXAwHX0dN@mail.gmail.com> <AANLkTimNK6MyDq=1Z5CsUz4HxgeMKq4oG7nUM7W09UCb@mail.gmail.com> <AANLkTintqbVr0VjBfU+2k_iYM-E9ss8AEAnV8wyrGhJN@mail.gmail.com> <4CFD1C22.3090900@gmail.com> <AANLkTi=uSGqX8bi0ZLKoqnrqKEXNUof6LXemfX6Uf6uw@mail.gmail.com> <4CFD2933.6040800@gmail.com> <AANLkTinjJzQL4zmtJqaX=BUPX8vPz-aXfVvhkH5WYgYk@mail.gmail.com> <20101206232928.GA15607@bubble.grove.modra.org> <mcr39q14c0i.fsf@google.com> <mcrr5c9buv5.fsf@google.com>
On Tue, Jan 18, 2011 at 04:27:42PM -0800, Ian Lance Taylor wrote:
> After some discussion on IRC, here is another approach to resolving the
> issue with static linking and LTO.
>
> In this approach, the linker keeps track of all archives found after the
> first file claimed by the plugin. If the plugin adds any object files,
> and the object files refer to any symbols which are not yet defined,
> then the linker will scan all the saved archives, in order, for a
> definition of the symbol. If a definition is found, the linker will
> pull in the appropriate object from the archive. If that object, in
> turn, has any undefined symbols, the linker will pull in the appropriate
> object from that archive or any later ones, and so forth. The linker
> will honor --start-group/--end-group while rescanning.
This quite simple patch does the same for GNU ld, except that I don't
bother to differentiate between archives found before the first
claimed file and those after. I'll address that with a followup patch.
PR ld/12672
* ldlang.c (enum open_bfd_mode): New.
(open_input_bfds): Replace "force" param with "mode". Reload
archives for rescan. Update all callers.
(lang_process): Make another open_input_bfds pass for plugins.
Index: ld/ldlang.c
===================================================================
RCS file: /cvs/src/src/ld/ldlang.c,v
retrieving revision 1.364
diff -u -p -r1.364 ldlang.c
--- ld/ldlang.c 10 Mar 2011 10:26:26 -0000 1.364
+++ ld/ldlang.c 15 Apr 2011 02:18:49 -0000
@@ -3174,26 +3174,34 @@ init_opb (void)
/* Open all the input files. */
+enum open_bfd_mode
+ {
+ OPEN_BFD_NORMAL = 0,
+ OPEN_BFD_FORCE = 1,
+ OPEN_BFD_RESCAN = 2
+ };
+
static void
-open_input_bfds (lang_statement_union_type *s, bfd_boolean force)
+open_input_bfds (lang_statement_union_type *s, enum open_bfd_mode mode)
{
for (; s != NULL; s = s->header.next)
{
switch (s->header.type)
{
case lang_constructors_statement_enum:
- open_input_bfds (constructor_list.head, force);
+ open_input_bfds (constructor_list.head, mode);
break;
case lang_output_section_statement_enum:
- open_input_bfds (s->output_section_statement.children.head, force);
+ open_input_bfds (s->output_section_statement.children.head, mode);
break;
case lang_wild_statement_enum:
/* Maybe we should load the file's symbols. */
- if (s->wild_statement.filename
+ if ((mode & OPEN_BFD_RESCAN) == 0
+ && s->wild_statement.filename
&& !wildcardp (s->wild_statement.filename)
&& !archive_path (s->wild_statement.filename))
lookup_name (s->wild_statement.filename);
- open_input_bfds (s->wild_statement.children.head, force);
+ open_input_bfds (s->wild_statement.children.head, mode);
break;
case lang_group_statement_enum:
{
@@ -3206,7 +3214,8 @@ open_input_bfds (lang_statement_union_ty
do
{
undefs = link_info.hash->undefs_tail;
- open_input_bfds (s->group_statement.children.head, TRUE);
+ open_input_bfds (s->group_statement.children.head,
+ mode | OPEN_BFD_FORCE);
}
while (undefs != link_info.hash->undefs_tail);
}
@@ -3225,8 +3234,8 @@ open_input_bfds (lang_statement_union_ty
/* If we are being called from within a group, and this
is an archive which has already been searched, then
force it to be researched unless the whole archive
- has been loaded already. */
- if (force
+ has been loaded already. Do the same for a rescan. */
+ if (mode != OPEN_BFD_NORMAL
&& !s->input_statement.whole_archive
&& s->input_statement.loaded
&& bfd_check_format (s->input_statement.the_bfd,
@@ -6468,7 +6477,7 @@ lang_process (void)
/* Create a bfd for each input file. */
current_target = default_target;
- open_input_bfds (statement_list.head, FALSE);
+ open_input_bfds (statement_list.head, OPEN_BFD_NORMAL);
#ifdef ENABLE_PLUGINS
if (plugin_active_plugins_p ())
@@ -6489,7 +6498,7 @@ lang_process (void)
einfo (_("%P%F: %s: plugin reported error after all symbols read\n"),
plugin_error_plugin ());
/* Open any newly added files, updating the file chains. */
- open_input_bfds (added.head, FALSE);
+ open_input_bfds (added.head, OPEN_BFD_NORMAL);
/* Restore the global list pointer now they have all been added. */
lang_list_remove_tail (stat_ptr, &added);
/* And detach the fresh ends of the file lists. */
@@ -6519,6 +6528,8 @@ lang_process (void)
else
lang_list_insert_after (&file_chain, &files, &file_chain.head);
}
+ /* Rescan any archives in case new undefined symbols have appeared. */
+ open_input_bfds (statement_list.head, OPEN_BFD_RESCAN);
}
#endif /* ENABLE_PLUGINS */
--
Alan Modra
Australia Development Lab, IBM