PR ld/12365

PR ld/12672
bfd/
	* bfd.c (BFD_PLUGIN): Define.
	(BFD_FLAGS_SAVED, BFD_FLAGS_FOR_BFD_USE_MASK): Add BFD_PLUGIN.
	* bfd-in2.h: Regenerate.
	* elflink.c (elf_link_output_extsym): Strip undefined plugin syms.
	* opncls.c (bfd_make_readable): Don't lose original bfd flags.
ld/
	* ldfile.c (ldfile_try_open_bfd): Don't attempt any plugin action
	when no_more_claiming.
	* ldmain.c (add_archive_element): Likewise.
	(multiple_definition): Remove plugin_multiple_definition call.
	(notice): Remove plugin_notice call.
	* ldlang.c (lang_list_insert_after, void lang_list_remove_tail): Move.
	Delete prototype.
	(plugin_insert): New static var.
	(open_input_bfds): Only rescan libs after plugin insert point.
	(lang_gc_sections): Omit plugin claimed files.
	(lang_process): Set plugin_insert.  Only rescan when plugin adds
	objects.
	* plugin.h (no_more_claiming): Declare.
	(plugin_notice, plugin_multiple_definition): Don't declare.
	* plugin.c: Formatting.
	(orig_notice_all, orig_allow_multiple_defs, orig_callbacks,
	plugin_callbacks): New static vars.
	(no_more_claiming): Make global.
	(plugin_cached_allow_multiple_defs): Delete.
	(plugin_get_ir_dummy_bfd): Set SEC_EXCLUDE on dummy .text section,
	use newer bfd_make_section variant.  Make COMMON section too.
	Error handling.  Correct setting of gp size.
	(asymbol_from_plugin_symbol): Properly cast last arg of concat.
	(message): Likewise for ACONCAT.
	(asymbol_from_plugin_symbol): Use our COMMON section.
	(get_symbols): When report_plugin_symbols, show visibility too.
	(init_non_ironly_hash): Move.  Don't test non_ironly_hash.
	(plugin_load_plugins): Save state of linker callbacks, set up to
	call plugin_notice instead.  Call init_non_ironly_hash here.
	(plugin_call_all_symbols_read): Set plugin_multiple_definition in
	plugin callbacks.
	(plugin_notice): Rewrite.
	(plugin_multiple_definition): Make static, call original callback.
ld/testsuite/
	* ld-plugin/plugin-7.d: Adjust for plugin changes.
	* ld-plugin/plugin-8.d: Likewise.
	* ld-plugin/plugin.exp: Pass --verbose=2 for visibility test, and
	compare ld output to..
	* ld-plugin/plugin-12.d: New.
This commit is contained in:
Alan Modra
2011-04-17 23:15:13 +00:00
parent 0283589814
commit 9e2278f567
13 changed files with 223 additions and 184 deletions

View File

@@ -86,13 +86,6 @@ static void print_statement_list (lang_statement_union_type *,
static void print_statements (void);
static void print_input_section (asection *, bfd_boolean);
static bfd_boolean lang_one_common (struct bfd_link_hash_entry *, void *);
#ifdef ENABLE_PLUGINS
static void lang_list_insert_after (lang_statement_list_type *destlist,
lang_statement_list_type *srclist,
lang_statement_union_type **field);
static void lang_list_remove_tail (lang_statement_list_type *destlist,
lang_statement_list_type *origlist);
#endif /* ENABLE_PLUGINS */
static void lang_record_phdrs (void);
static void lang_do_version_exports_section (void);
static void lang_finalize_version_expr_head
@@ -3180,6 +3173,9 @@ enum open_bfd_mode
OPEN_BFD_FORCE = 1,
OPEN_BFD_RESCAN = 2
};
#ifdef ENABLE_PLUGINS
static lang_input_statement_type *plugin_insert = NULL;
#endif
static void
open_input_bfds (lang_statement_union_type *s, enum open_bfd_mode mode)
@@ -3236,6 +3232,10 @@ open_input_bfds (lang_statement_union_type *s, enum open_bfd_mode mode)
force it to be researched unless the whole archive
has been loaded already. Do the same for a rescan. */
if (mode != OPEN_BFD_NORMAL
#ifdef ENABLE_PLUGINS
&& ((mode & OPEN_BFD_RESCAN) == 0
|| plugin_insert == NULL)
#endif
&& !s->input_statement.whole_archive
&& s->input_statement.loaded
&& bfd_check_format (s->input_statement.the_bfd,
@@ -3271,6 +3271,12 @@ open_input_bfds (lang_statement_union_type *s, enum open_bfd_mode mode)
}
}
}
#ifdef ENABLE_PLUGINS
/* If we have found the point at which a plugin added new
files, clear plugin_insert to enable archive rescan. */
if (&s->input_statement == plugin_insert)
plugin_insert = NULL;
#endif
break;
case lang_assignment_statement_enum:
if (s->assignment_statement.exp->assign.hidden)
@@ -6279,6 +6285,10 @@ lang_gc_sections (void)
LANG_FOR_EACH_INPUT_STATEMENT (f)
{
asection *sec;
#ifdef ENABLE_PLUGINS
if (f->claimed)
continue;
#endif
for (sec = f->the_bfd->sections; sec != NULL; sec = sec->next)
if ((sec->flags & SEC_DEBUGGING) == 0)
sec->flags &= ~SEC_EXCLUDE;
@@ -6452,6 +6462,38 @@ find_replacements_insert_point (void)
insert point. */
return lastobject;
}
/* Insert SRCLIST into DESTLIST after given element by chaining
on FIELD as the next-pointer. (Counterintuitively does not need
a pointer to the actual after-node itself, just its chain field.) */
static void
lang_list_insert_after (lang_statement_list_type *destlist,
lang_statement_list_type *srclist,
lang_statement_union_type **field)
{
*(srclist->tail) = *field;
*field = srclist->head;
if (destlist->tail == field)
destlist->tail = srclist->tail;
}
/* Detach new nodes added to DESTLIST since the time ORIGLIST
was taken as a copy of it and leave them in ORIGLIST. */
static void
lang_list_remove_tail (lang_statement_list_type *destlist,
lang_statement_list_type *origlist)
{
union lang_statement_union **savetail;
/* Check that ORIGLIST really is an earlier state of DESTLIST. */
ASSERT (origlist->head == destlist->head);
savetail = origlist->tail;
origlist->head = *(savetail);
origlist->tail = destlist->tail;
destlist->tail = savetail;
*savetail = NULL;
}
#endif /* ENABLE_PLUGINS */
void
@@ -6484,6 +6526,7 @@ lang_process (void)
{
lang_statement_list_type added;
lang_statement_list_type files, inputfiles;
/* Now all files are read, let the plugin(s) decide if there
are any more to be added to the link before we call the
emulation's after_open hook. We create a private list of
@@ -6509,27 +6552,29 @@ lang_process (void)
{
/* If so, we will insert them into the statement list immediately
after the first input file that was claimed by the plugin. */
lang_input_statement_type *claim1 = find_replacements_insert_point ();
plugin_insert = find_replacements_insert_point ();
/* If a plugin adds input files without having claimed any, we
don't really have a good idea where to place them. Just putting
them at the start or end of the list is liable to leave them
outside the crtbegin...crtend range. */
ASSERT (claim1 != NULL);
/* Splice the new statement list into the old one after claim1. */
lang_list_insert_after (stat_ptr, &added, &claim1->header.next);
ASSERT (plugin_insert != NULL);
/* Splice the new statement list into the old one. */
lang_list_insert_after (stat_ptr, &added,
&plugin_insert->header.next);
/* Likewise for the file chains. */
lang_list_insert_after (&input_file_chain, &inputfiles,
&claim1->next_real_file);
&plugin_insert->next_real_file);
/* We must be careful when relinking file_chain; we may need to
insert the new files at the head of the list if the insert
point chosen is the dummy first input file. */
if (claim1->filename)
lang_list_insert_after (&file_chain, &files, &claim1->next);
if (plugin_insert->filename)
lang_list_insert_after (&file_chain, &files, &plugin_insert->next);
else
lang_list_insert_after (&file_chain, &files, &file_chain.head);
/* Rescan archives in case new undefined symbols have appeared. */
open_input_bfds (statement_list.head, OPEN_BFD_RESCAN);
}
/* Rescan any archives in case new undefined symbols have appeared. */
open_input_bfds (statement_list.head, OPEN_BFD_RESCAN);
}
#endif /* ENABLE_PLUGINS */
@@ -6952,40 +6997,6 @@ lang_statement_append (lang_statement_list_type *list,
list->tail = field;
}
#ifdef ENABLE_PLUGINS
/* Insert SRCLIST into DESTLIST after given element by chaining
on FIELD as the next-pointer. (Counterintuitively does not need
a pointer to the actual after-node itself, just its chain field.) */
static void
lang_list_insert_after (lang_statement_list_type *destlist,
lang_statement_list_type *srclist,
lang_statement_union_type **field)
{
*(srclist->tail) = *field;
*field = srclist->head;
if (destlist->tail == field)
destlist->tail = srclist->tail;
}
/* Detach new nodes added to DESTLIST since the time ORIGLIST
was taken as a copy of it and leave them in ORIGLIST. */
static void
lang_list_remove_tail (lang_statement_list_type *destlist,
lang_statement_list_type *origlist)
{
union lang_statement_union **savetail;
/* Check that ORIGLIST really is an earlier state of DESTLIST. */
ASSERT (origlist->head == destlist->head);
savetail = origlist->tail;
origlist->head = *(savetail);
origlist->tail = destlist->tail;
destlist->tail = savetail;
*savetail = NULL;
}
#endif /* ENABLE_PLUGINS */
/* Set the output format type. -oformat overrides scripts. */
void