From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 27721 invoked by alias); 26 Feb 2011 00:48:54 -0000 Received: (qmail 27711 invoked by uid 22791); 26 Feb 2011 00:48:53 -0000 X-SWARE-Spam-Status: No, hits=-2.1 required=5.0 tests=AWL,BAYES_00,DKIM_SIGNED,DKIM_VALID,DKIM_VALID_AU,FREEMAIL_FROM,RCVD_IN_DNSWL_LOW,TW_FD,TW_TM,TW_YY X-Spam-Check-By: sourceware.org Received: from mail-wy0-f169.google.com (HELO mail-wy0-f169.google.com) (74.125.82.169) by sourceware.org (qpsmtpd/0.43rc1) with ESMTP; Sat, 26 Feb 2011 00:48:48 +0000 Received: by mail-wy0-f169.google.com with SMTP id 11so2570441wyi.0 for ; Fri, 25 Feb 2011 16:48:47 -0800 (PST) Received: by 10.227.128.199 with SMTP id l7mr2744417wbs.45.1298681327755; Fri, 25 Feb 2011 16:48:47 -0800 (PST) Received: from [192.168.2.99] (cpc2-cmbg8-0-0-cust61.5-4.cable.virginmedia.com [82.6.108.62]) by mx.google.com with ESMTPS id u9sm1027749wbg.12.2011.02.25.16.48.46 (version=SSLv3 cipher=OTHER); Fri, 25 Feb 2011 16:48:46 -0800 (PST) Message-ID: <4D684DDB.6090501@gmail.com> Date: Sat, 26 Feb 2011 00:48:00 -0000 From: Dave Korn User-Agent: Thunderbird 2.0.0.17 (Windows/20080914) MIME-Version: 1.0 To: "binutils@sourceware.org" Subject: Re: [5/6][PATCH] Perform second link stage and ignore now-obsolete linker -pass-through= option. References: <4D684CB8.6020106@gmail.com> <4D684D00.70803@gmail.com> <4D684D69.7060907@gmail.com> In-Reply-To: <4D684D69.7060907@gmail.com> Content-Type: multipart/mixed; boundary="------------010803000304090603040402" Mailing-List: contact binutils-help@sourceware.org; run by ezmlm Precedence: bulk List-Id: List-Subscribe: List-Archive: List-Post: List-Help: , Sender: binutils-owner@sourceware.org X-SW-Source: 2011-02/txt/msg00337.txt.bz2 This is a multi-part message in MIME format. --------------010803000304090603040402 Content-Type: text/plain; charset=ISO-8859-1 Content-Transfer-Encoding: 7bit Content-length: 114 On 26/02/2011 00:46, Dave Korn wrote: I started forgetting to add the patches about half-way through there... --------------010803000304090603040402 Content-Type: text/x-c; name="005ld-link-stage2.diff" Content-Transfer-Encoding: 7bit Content-Disposition: attachment; filename="005ld-link-stage2.diff" Content-length: 6602 >From 8fb73a8834169d39ed90c5dcf25a1cdf62e95e09 Mon Sep 17 00:00:00 2001 From: Dave Korn Date: Sun, 20 Feb 2011 00:38:54 +0000 Subject: [PATCH] Perform second link stage and ignore now-obsolete linker -pass-through= option. ld/ChangeLog: 2011-02-20 Dave Korn <... PR ld/12365 * ldcref.c (cref_hash_table_free): New function. * ld.h (cref_hash_table_free): Add prototype. * ldlang.c (lang_gc_sections): Dont de-exclude claimed file sections. (set_exclude): New function. (reopen_inputs): Likewise. Walk list of input objects, excluding claimed (IR-only) files and archive members, then re-walk list, closing and re-opening and re-adding the symbols from objects and libs. (lang_process): After opening plugin-supplied objects and scanning their library dependencies, tear down existing link, cref and already-linked-section hashes, erase link_info input bfds list, finally call reopen_inputs. * plugin.c (plugin_opt_plugin_arg): Discard any instances of the now-obsolete "-pass-through=" option if found. --- ld/ld.h | 1 + ld/ldcref.c | 18 +++++++++++ ld/ldlang.c | 93 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ ld/plugin.c | 3 ++ 4 files changed, 115 insertions(+), 0 deletions(-) diff --git a/ld/ld.h b/ld/ld.h index 564cb73..dfa3f2e 100644 --- a/ld/ld.h +++ b/ld/ld.h @@ -327,6 +327,7 @@ extern int parsing_defsym; extern int yyparse (void); extern void add_cref (const char *, bfd *, asection *, bfd_vma); +extern void cref_hash_table_free (void); extern bfd_boolean handle_asneeded_cref (bfd *, enum notice_asneeded_action); extern void output_cref (FILE *); extern void check_nocrossrefs (void); diff --git a/ld/ldcref.c b/ld/ldcref.c index 2f6a46c..889b38a 100644 --- a/ld/ldcref.c +++ b/ld/ldcref.c @@ -198,6 +198,24 @@ add_cref (const char *name, r->def = TRUE; } +/* Free the cref hash table. */ + +void +cref_hash_table_free (void) +{ + if (cref_initialized) + { + bfd_hash_table_free (&cref_table.root); + cref_initialized = FALSE; + cref_symcount = 0; + old_table = NULL; + old_size = 0; + old_count = 0; + old_symcount = 0; + alloc_mark = NULL; + } +} + /* Called before loading an as-needed library to take a snapshot of the cref hash table, and after we have loaded or found that the library was not needed. */ diff --git a/ld/ldlang.c b/ld/ldlang.c index 7a1753d..7330dc0 100644 --- a/ld/ldlang.c +++ b/ld/ldlang.c @@ -6269,6 +6269,10 @@ lang_gc_sections (void) LANG_FOR_EACH_INPUT_STATEMENT (f) { asection *sec; +#ifdef ENABLE_PLUGINS + if (f->claimed) + continue; +#endif /* ENABLE_PLUGINS */ for (sec = f->the_bfd->sections; sec != NULL; sec = sec->next) if ((sec->flags & SEC_DEBUGGING) == 0) sec->flags &= ~SEC_EXCLUDE; @@ -6442,6 +6446,69 @@ find_replacements_insert_point (void) insert point. */ return lastobject; } + +/* Mapped over sections of claimed IR BFDs to exclude them from the + final link. */ + +static void +set_exclude (bfd *abfd, asection *sect, void *obj ATTRIBUTE_UNUSED) +{ + bfd_set_section_flags (abfd, + sect, + SEC_EXCLUDE | bfd_get_section_flags (abfd, sect)); + sect->output_section = NULL; +} + +/* This runs two passes over the inputs. First we exclude any IR + BFDs and archive members from the link; then we re-run it by + re-opening all the object files and archives and re-adding + their symbols to the fresh linker hash table. */ + +static void +reopen_inputs (void) +{ + lang_input_statement_type *stmt; + + /* Exclude dummy IR files and archive members. */ + for (stmt = &file_chain.head->input_statement; + stmt != NULL; + stmt = &stmt->next->input_statement) + { + if (stmt->claimed || (stmt->the_bfd && bfd_my_archive (stmt->the_bfd))) + { + bfd_map_over_sections (stmt->the_bfd, set_exclude, 0); + stmt->claimed = TRUE; + } + } + + /* Re-open real objects and libs, recalculating link as we go. */ + for (stmt = &input_file_chain.head->input_statement; + stmt != NULL; + stmt = &stmt->next_real_file->input_statement) + { + if (!stmt->claimed && stmt->the_bfd && !bfd_my_archive (stmt->the_bfd)) + { + bfd *oldbfd = stmt->the_bfd; + stmt->the_bfd = NULL; + ldfile_open_file (stmt); + bfd_check_format (stmt->the_bfd, bfd_get_format (oldbfd)); + if (bfd_get_format (stmt->the_bfd) != bfd_archive) + { + *link_info.input_bfds_tail = stmt->the_bfd; + stmt->the_bfd->link_next = NULL; + link_info.input_bfds_tail = &stmt->the_bfd->link_next; + } + stmt->the_bfd->usrdata = stmt; + bfd_set_gp_size (stmt->the_bfd, g_switch_value); + bfd_map_over_sections (stmt->the_bfd, section_already_linked, stmt); + bfd_link_add_symbols (stmt->the_bfd, &link_info); + /* We need to hold archive BFDs open while we still have statements + indicating them; plain object files we are finished with now. */ + if (bfd_get_format (oldbfd) == bfd_object) + bfd_close (oldbfd); + } + } +} #endif /* ENABLE_PLUGINS */ void @@ -6518,6 +6585,32 @@ lang_process (void) else lang_list_insert_after (&file_chain, &files, &file_chain.head); } + + /* Free the old already linked table and create a new one. */ + bfd_section_already_linked_table_free (); + if (!bfd_section_already_linked_table_init ()) + einfo (_("%P%F: Failed to create hash table\n")); + + /* Free the old hash table and create a new one. */ + bfd_link_hash_table_free (link_info.output_bfd, + link_info.hash); + link_info.hash + = bfd_link_hash_table_create (link_info.output_bfd); + if (link_info.hash == NULL) + einfo (_("%P%F: can not create hash table: %E\n")); + + /* Re-add to the hash table all undefineds on the command line. */ + lang_place_undefineds (); + + /* Free the old cref hash table. */ + cref_hash_table_free (); + + /* And relink the input bfds list. */ + link_info.input_bfds = NULL; + link_info.input_bfds_tail = &link_info.input_bfds; + + /* Now run round the input objects re-adding symbols. */ + reopen_inputs (); } #endif /* ENABLE_PLUGINS */ diff --git a/ld/plugin.c b/ld/plugin.c index c1672f6..db3ad07 100644 --- a/ld/plugin.c +++ b/ld/plugin.c @@ -207,6 +207,9 @@ plugin_opt_plugin_arg (const char *arg) if (!last_plugin) return set_plugin_error (_("")); + if (CONST_STRNEQ (arg, "-pass-through=")) + return 0; + newarg = xmalloc (sizeof *newarg); newarg->arg = arg; newarg->next = NULL; --------------010803000304090603040402--