On Wed, Jan 19, 2011 at 1:27 AM, Ian Lance Taylor <i...@google.com> 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 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.
Nice. Can we on the GCC side somehow identify Gold versions that support this and avoid -pass-through handling in that case? I'm not sure if with your patch the add_input_library or add_input_file plugin hooks are completely useless (and thus gold could simply ignore those at all). Richard. > Ian > > > 2011-01-18 Ian Lance Taylor <i...@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. > > >