From 1f1f5b92e811e9c7485129c065a9ff2c409303a4 Mon Sep 17 00:00:00 2001 From: Alan Modra Date: Fri, 13 Sep 2019 11:09:41 +0930 Subject: [PATCH] Always add input_statement to statement_list I think this is safer than leaving an input_statement added during open_input_bfds off the list. There are a number of places that fiddle with various lists and might be confused by an off-list statement, eg. orphan handling. * ldlang.c (new_afile): Remove add_to_list parameter. (lang_add_input_file): Update new_afile calls. (lookup_name): Splice input_statement added by new_afile into statement_list after current input_file_chain entry. (lang_process): Update comment. --- ld/ChangeLog | 8 ++++++++ ld/ldlang.c | 41 ++++++++++++++++++++++++----------------- 2 files changed, 32 insertions(+), 17 deletions(-) diff --git a/ld/ChangeLog b/ld/ChangeLog index a39cfad3e6..b2d4151716 100644 --- a/ld/ChangeLog +++ b/ld/ChangeLog @@ -1,3 +1,11 @@ +2019-09-13 Alan Modra + + * ldlang.c (new_afile): Remove add_to_list parameter. + (lang_add_input_file): Update new_afile calls. + (lookup_name): Splice input_statement added by new_afile into + statement_list after current input_file_chain entry. + (lang_process): Update comment. + 2019-09-12 Alan Modra * ldlang.c (print_input_statement): Do not exclude linker created diff --git a/ld/ldlang.c b/ld/ldlang.c index 7b381ef2d5..8beccd3736 100644 --- a/ld/ldlang.c +++ b/ld/ldlang.c @@ -1080,22 +1080,13 @@ new_statement (enum statement_enum type, static lang_input_statement_type * new_afile (const char *name, lang_input_file_enum_type file_type, - const char *target, - bfd_boolean add_to_list) + const char *target) { lang_input_statement_type *p; lang_has_input_file = TRUE; - if (add_to_list) - p = new_stat (lang_input_statement, stat_ptr); - else - { - p = stat_alloc (sizeof (lang_input_statement_type)); - p->header.type = lang_input_statement_enum; - p->header.next = NULL; - } - + p = new_stat (lang_input_statement, stat_ptr); memset (&p->the_bfd, 0, sizeof (*p) - offsetof (lang_input_statement_type, the_bfd)); p->target = target; @@ -1177,12 +1168,12 @@ lang_add_input_file (const char *name, within the sysroot subdirectory.) */ unsigned int outer_sysrooted = input_flags.sysrooted; input_flags.sysrooted = 0; - ret = new_afile (sysrooted_name, file_type, target, TRUE); + ret = new_afile (sysrooted_name, file_type, target); input_flags.sysrooted = outer_sysrooted; return ret; } - return new_afile (name, file_type, target, TRUE); + return new_afile (name, file_type, target); } struct out_section_hash_entry @@ -2861,8 +2852,25 @@ lookup_name (const char *name) } if (search == NULL) - search = new_afile (name, lang_input_file_is_search_file_enum, - default_target, FALSE); + { + /* Arrange to splice the input statement added by new_afile into + statement_list after the current input_file_chain tail. + We know input_file_chain is not an empty list, and that + lookup_name was called via open_input_bfds. Later calls to + lookup_name should always match an existing input_statement. */ + lang_statement_union_type **tail = stat_ptr->tail; + lang_statement_union_type **after + = (void *) ((char *) input_file_chain.tail + - offsetof (lang_input_statement_type, next_real_file) + + offsetof (lang_input_statement_type, header.next)); + lang_statement_union_type *rest = *after; + stat_ptr->tail = after; + search = new_afile (name, lang_input_file_is_search_file_enum, + default_target); + *stat_ptr->tail = rest; + if (*tail == NULL) + stat_ptr->tail = tail; + } /* If we have already added this file, or this file is not real don't add this file. */ @@ -7501,8 +7509,7 @@ lang_process (void) if (*prev != (void *) plugin_insert->next_real_file) { /* We didn't find the expected input statement. - This can happen due to lookup_name creating input - statements not linked into the statement list. */ + Fall back to adding after plugin_insert. */ prev = &plugin_insert->header.next; } }