PATCH: 2 stage BFD linker for LTO plugin

Ian Lance Taylor iant@google.com
Wed Jan 19 00:28:00 GMT 2011


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 should ensure that any previously unseen undefined symbols
introduced by the compiler are handled correctly.  I think it is
appropriate to do this unconditionally when using plugins, as there is
no other reasonable way to handle undefined symbols in a file added by a
plugin.

I've appended a patch to gold which implements this approach.  The patch
is reasonably efficient and introduces no unnecessary file I/O.  With
this patch to gold, and no change to gcc, the problematic -static test
cases which I know about pass.  Also all the current lto.exp tests pass.
All those tests also pass if I edit the gcc LTO plugin to ignore the
-pass-through option, as that option is not necessary when the linker
implements this approach.

As this patch does not require any changes to gcc, and fixes some cases
which are clearly bugs, I plan to commit this patch to binutils mainline
and to binutils 2.21 branch after a few days if I don't hear any
comments.

Ian


2011-01-18  Ian Lance Taylor  <iant@google.com>

	* plugin.cc (class Plugin_rescan): Define new class.
	(Plugin_manager::claim_file): Set any_claimed_.
	(Plugin_manager::save_archive): New function.
	(Plugin_manager::save_input_group): New function.
	(Plugin_manager::all_symbols_read): Create Plugin_rescan task if
	necessary.
	(Plugin_manager::new_undefined_symbol): New function.
	(Plugin_manager::rescan): New function.
	(Plugin_manager::rescannable_defines): New function.
	(Plugin_manager::add_input_file): Set any_added_.
	* plugin.h (class Plugin_manager): define new fields rescannable_,
	undefined_symbols_, any_claimed_, and any_added_.  Declare
	Plugin_rescan as friend.  Declare new functions.
	(Plugin_manager::Rescannable): Define type.
	(Plugin_manager::Rescannable_list): Define type.
	(Plugin_manager::Undefined_symbol_list): Define type.
	(Plugin_manager::Plugin_manager): Initialize new fields.
	* archive.cc (Archive::defines_symbol): New function.
	(Add_archive_symbols::run): Pass archive to plugins if any.
	* archive.h (class Archive): Declare defines_symbol.
	* readsyms.cc (Input_group::~Input_group): New function.
	(Finish_group::run): Pass input_group to plugins if any.
	* readsyms.h (class Input_group): Declare destructor.
	* symtab.cc (add_from_object): Pass undefined symbol to plugins if
	any.


-------------- next part --------------
A non-text attachment was scrubbed...
Name: foo.patch
Type: text/x-diff
Size: 15942 bytes
Desc: gold
URL: <https://sourceware.org/pipermail/binutils/attachments/20110119/f5294601/attachment.bin>


More information about the Binutils mailing list