aboutsummaryrefslogtreecommitdiff
path: root/ld/ldlang.c
diff options
context:
space:
mode:
authorAlan Modra <amodra@gmail.com>2019-09-13 11:09:41 +0930
committerAlan Modra <amodra@gmail.com>2019-09-13 12:43:42 +0930
commit1f1f5b92e811e9c7485129c065a9ff2c409303a4 (patch)
tree4e74326d61d5579cc6e04e4c614bb48f83b015bd /ld/ldlang.c
parentec6c8338a89b0ec022b66ed3efdd1577e6449d6d (diff)
downloadbinutils-1f1f5b92e811e9c7485129c065a9ff2c409303a4.zip
binutils-1f1f5b92e811e9c7485129c065a9ff2c409303a4.tar.gz
binutils-1f1f5b92e811e9c7485129c065a9ff2c409303a4.tar.bz2
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.
Diffstat (limited to 'ld/ldlang.c')
-rw-r--r--ld/ldlang.c41
1 files changed, 24 insertions, 17 deletions
diff --git a/ld/ldlang.c b/ld/ldlang.c
index 7b381ef..8beccd3 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;
}
}