summaryrefslogtreecommitdiff
path: root/ld/ldlang.c
diff options
context:
space:
mode:
authorAlan Modra <amodra@bigpond.net.au>2011-04-17 23:15:11 +0000
committerAlan Modra <amodra@bigpond.net.au>2011-04-17 23:15:11 +0000
commit4b96312bb623ba76b035ac3b3c5afe583bebca76 (patch)
tree9a396f739669b870d2709649cdab1ef97f45eb81 /ld/ldlang.c
parent928c816e72640c7a8d9e39aaa41a5814aeea6a17 (diff)
downloadbinutils-redhat-4b96312bb623ba76b035ac3b3c5afe583bebca76.tar.gz
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.
Diffstat (limited to 'ld/ldlang.c')
-rw-r--r--ld/ldlang.c111
1 files changed, 61 insertions, 50 deletions
diff --git a/ld/ldlang.c b/ld/ldlang.c
index 08bfa60f69..2c07fa4d35 100644
--- a/ld/ldlang.c
+++ b/ld/ldlang.c
@@ -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