diff options
author | Alan Modra <amodra@gmail.com> | 2011-04-17 23:15:13 +0000 |
---|---|---|
committer | Alan Modra <amodra@gmail.com> | 2011-04-17 23:15:13 +0000 |
commit | 9e2278f567e4ddeb7180ef4e0b3b24e4b087d703 (patch) | |
tree | e917203967fd03ed383ff7a74bd7aee910acf4dc /ld/ldlang.c | |
parent | 0283589814e341df59ca48e497ff6671fbcb5955 (diff) | |
download | gdb-9e2278f567e4ddeb7180ef4e0b3b24e4b087d703.zip gdb-9e2278f567e4ddeb7180ef4e0b3b24e4b087d703.tar.gz gdb-9e2278f567e4ddeb7180ef4e0b3b24e4b087d703.tar.bz2 |
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.c | 111 |
1 files changed, 61 insertions, 50 deletions
diff --git a/ld/ldlang.c b/ld/ldlang.c index 08bfa60..2c07fa4 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 |