|
|
|
@ -69,7 +69,6 @@ static struct bfd_hash_table lang_definedness_table; |
|
|
|
static lang_statement_list_type *stat_save[10]; |
|
|
|
static lang_statement_list_type **stat_save_ptr = &stat_save[0]; |
|
|
|
static struct unique_sections *unique_section_list; |
|
|
|
static bfd_boolean ldlang_sysrooted_script = FALSE; |
|
|
|
|
|
|
|
/* Forward declarations. */ |
|
|
|
static void exp_init_os (etree_type *); |
|
|
|
@ -100,6 +99,7 @@ lang_statement_list_type file_chain = { NULL, NULL }; |
|
|
|
lang_statement_list_type input_file_chain; |
|
|
|
struct bfd_sym_chain entry_symbol = { NULL, NULL }; |
|
|
|
const char *entry_section = ".text"; |
|
|
|
struct lang_input_statement_flags input_flags; |
|
|
|
bfd_boolean entry_from_cmdline; |
|
|
|
bfd_boolean undef_from_cmdline; |
|
|
|
bfd_boolean lang_has_input_file = FALSE; |
|
|
|
@ -108,7 +108,6 @@ bfd_boolean lang_float_flag = FALSE; |
|
|
|
bfd_boolean delete_output_file_on_failure = FALSE; |
|
|
|
struct lang_phdr *lang_phdr_list; |
|
|
|
struct lang_nocrossrefs *nocrossref_list; |
|
|
|
bfd_boolean missing_file = FALSE; |
|
|
|
|
|
|
|
/* Functions that traverse the linker script and might evaluate
|
|
|
|
DEFINED() need to increment this. */ |
|
|
|
@ -731,7 +730,7 @@ walk_wild_section (lang_wild_statement_type *ptr, |
|
|
|
callback_t callback, |
|
|
|
void *data) |
|
|
|
{ |
|
|
|
if (file->just_syms_flag) |
|
|
|
if (file->flags.just_syms) |
|
|
|
return; |
|
|
|
|
|
|
|
(*ptr->walk_wild_section_handler) (ptr, file, callback, data); |
|
|
|
@ -1046,6 +1045,8 @@ new_afile (const char *name, |
|
|
|
{ |
|
|
|
lang_input_statement_type *p; |
|
|
|
|
|
|
|
lang_has_input_file = TRUE; |
|
|
|
|
|
|
|
if (add_to_list) |
|
|
|
p = (lang_input_statement_type *) new_stat (lang_input_statement, stat_ptr); |
|
|
|
else |
|
|
|
@ -1056,9 +1057,13 @@ new_afile (const char *name, |
|
|
|
p->header.next = NULL; |
|
|
|
} |
|
|
|
|
|
|
|
lang_has_input_file = TRUE; |
|
|
|
memset (&p->the_bfd, 0, |
|
|
|
sizeof (*p) - offsetof (lang_input_statement_type, the_bfd)); |
|
|
|
p->target = target; |
|
|
|
p->sysrooted = FALSE; |
|
|
|
p->flags.dynamic = input_flags.dynamic; |
|
|
|
p->flags.add_DT_NEEDED_for_dynamic = input_flags.add_DT_NEEDED_for_dynamic; |
|
|
|
p->flags.add_DT_NEEDED_for_regular = input_flags.add_DT_NEEDED_for_regular; |
|
|
|
p->flags.whole_archive = input_flags.whole_archive; |
|
|
|
|
|
|
|
if (file_type == lang_input_file_is_l_enum |
|
|
|
&& name[0] == ':' && name[1] != '\0') |
|
|
|
@ -1071,70 +1076,41 @@ new_afile (const char *name, |
|
|
|
{ |
|
|
|
case lang_input_file_is_symbols_only_enum: |
|
|
|
p->filename = name; |
|
|
|
p->maybe_archive = FALSE; |
|
|
|
p->real = TRUE; |
|
|
|
p->local_sym_name = name; |
|
|
|
p->just_syms_flag = TRUE; |
|
|
|
p->search_dirs_flag = FALSE; |
|
|
|
p->flags.real = TRUE; |
|
|
|
p->flags.just_syms = TRUE; |
|
|
|
break; |
|
|
|
case lang_input_file_is_fake_enum: |
|
|
|
p->filename = name; |
|
|
|
p->maybe_archive = FALSE; |
|
|
|
p->real = FALSE; |
|
|
|
p->local_sym_name = name; |
|
|
|
p->just_syms_flag = FALSE; |
|
|
|
p->search_dirs_flag = FALSE; |
|
|
|
break; |
|
|
|
case lang_input_file_is_l_enum: |
|
|
|
p->maybe_archive = TRUE; |
|
|
|
p->filename = name; |
|
|
|
p->real = TRUE; |
|
|
|
p->local_sym_name = concat ("-l", name, (const char *) NULL); |
|
|
|
p->just_syms_flag = FALSE; |
|
|
|
p->search_dirs_flag = TRUE; |
|
|
|
p->flags.maybe_archive = TRUE; |
|
|
|
p->flags.real = TRUE; |
|
|
|
p->flags.search_dirs = TRUE; |
|
|
|
break; |
|
|
|
case lang_input_file_is_marker_enum: |
|
|
|
p->filename = name; |
|
|
|
p->maybe_archive = FALSE; |
|
|
|
p->real = FALSE; |
|
|
|
p->local_sym_name = name; |
|
|
|
p->just_syms_flag = FALSE; |
|
|
|
p->search_dirs_flag = TRUE; |
|
|
|
p->flags.search_dirs = TRUE; |
|
|
|
break; |
|
|
|
case lang_input_file_is_search_file_enum: |
|
|
|
p->sysrooted = ldlang_sysrooted_script; |
|
|
|
p->filename = name; |
|
|
|
p->maybe_archive = FALSE; |
|
|
|
p->real = TRUE; |
|
|
|
p->local_sym_name = name; |
|
|
|
p->just_syms_flag = FALSE; |
|
|
|
p->search_dirs_flag = TRUE; |
|
|
|
p->flags.real = TRUE; |
|
|
|
p->flags.search_dirs = TRUE; |
|
|
|
p->flags.sysrooted = input_flags.sysrooted; |
|
|
|
break; |
|
|
|
case lang_input_file_is_file_enum: |
|
|
|
p->filename = name; |
|
|
|
p->maybe_archive = FALSE; |
|
|
|
p->real = TRUE; |
|
|
|
p->local_sym_name = name; |
|
|
|
p->just_syms_flag = FALSE; |
|
|
|
p->search_dirs_flag = FALSE; |
|
|
|
p->flags.real = TRUE; |
|
|
|
break; |
|
|
|
default: |
|
|
|
FAIL (); |
|
|
|
} |
|
|
|
p->the_bfd = NULL; |
|
|
|
p->next_real_file = NULL; |
|
|
|
p->next = NULL; |
|
|
|
p->dynamic = config.dynamic_link; |
|
|
|
p->add_DT_NEEDED_for_dynamic = add_DT_NEEDED_for_dynamic; |
|
|
|
p->add_DT_NEEDED_for_regular = add_DT_NEEDED_for_regular; |
|
|
|
p->whole_archive = whole_archive; |
|
|
|
p->loaded = FALSE; |
|
|
|
p->missing_file = FALSE; |
|
|
|
#ifdef ENABLE_PLUGINS |
|
|
|
p->claimed = FALSE; |
|
|
|
p->claim_archive = FALSE; |
|
|
|
p->reload = FALSE; |
|
|
|
#endif /* ENABLE_PLUGINS */ |
|
|
|
|
|
|
|
lang_statement_append (&input_file_chain, |
|
|
|
(lang_statement_union_type *) p, |
|
|
|
@ -2012,7 +1988,7 @@ lang_map (void) |
|
|
|
asection *s; |
|
|
|
|
|
|
|
if ((file->the_bfd->flags & (BFD_LINKER_CREATED | DYNAMIC)) != 0 |
|
|
|
|| file->just_syms_flag) |
|
|
|
|| file->flags.just_syms) |
|
|
|
continue; |
|
|
|
|
|
|
|
for (s = file->the_bfd->sections; s != NULL; s = s->next) |
|
|
|
@ -2234,7 +2210,7 @@ section_already_linked (bfd *abfd, asection *sec, void *data) |
|
|
|
|
|
|
|
/* If we are only reading symbols from this object, then we want to
|
|
|
|
discard all sections. */ |
|
|
|
if (entry->just_syms_flag) |
|
|
|
if (entry->flags.just_syms) |
|
|
|
{ |
|
|
|
bfd_link_just_syms (abfd, sec, &link_info); |
|
|
|
return; |
|
|
|
@ -2619,7 +2595,7 @@ lookup_name (const char *name) |
|
|
|
|
|
|
|
/* If we have already added this file, or this file is not real
|
|
|
|
don't add this file. */ |
|
|
|
if (search->loaded || !search->real) |
|
|
|
if (search->flags.loaded || !search->flags.real) |
|
|
|
return search; |
|
|
|
|
|
|
|
if (! load_symbols (search, NULL)) |
|
|
|
@ -2697,23 +2673,20 @@ load_symbols (lang_input_statement_type *entry, |
|
|
|
{ |
|
|
|
char **matching; |
|
|
|
|
|
|
|
if (entry->loaded) |
|
|
|
if (entry->flags.loaded) |
|
|
|
return TRUE; |
|
|
|
|
|
|
|
ldfile_open_file (entry); |
|
|
|
|
|
|
|
/* Do not process further if the file was missing. */ |
|
|
|
if (entry->missing_file) |
|
|
|
if (entry->flags.missing_file) |
|
|
|
return TRUE; |
|
|
|
|
|
|
|
if (! bfd_check_format (entry->the_bfd, bfd_archive) |
|
|
|
&& ! bfd_check_format_matches (entry->the_bfd, bfd_object, &matching)) |
|
|
|
{ |
|
|
|
bfd_error_type err; |
|
|
|
bfd_boolean save_ldlang_sysrooted_script; |
|
|
|
bfd_boolean save_add_DT_NEEDED_for_regular; |
|
|
|
bfd_boolean save_add_DT_NEEDED_for_dynamic; |
|
|
|
bfd_boolean save_whole_archive; |
|
|
|
struct lang_input_statement_flags save_flags; |
|
|
|
|
|
|
|
err = bfd_get_error (); |
|
|
|
|
|
|
|
@ -2739,30 +2712,26 @@ load_symbols (lang_input_statement_type *entry, |
|
|
|
entry->the_bfd = NULL; |
|
|
|
|
|
|
|
/* Try to interpret the file as a linker script. */ |
|
|
|
save_flags = input_flags; |
|
|
|
ldfile_open_command_file (entry->filename); |
|
|
|
|
|
|
|
push_stat_ptr (place); |
|
|
|
save_ldlang_sysrooted_script = ldlang_sysrooted_script; |
|
|
|
ldlang_sysrooted_script = entry->sysrooted; |
|
|
|
save_add_DT_NEEDED_for_regular = add_DT_NEEDED_for_regular; |
|
|
|
add_DT_NEEDED_for_regular = entry->add_DT_NEEDED_for_regular; |
|
|
|
save_add_DT_NEEDED_for_dynamic = add_DT_NEEDED_for_dynamic; |
|
|
|
add_DT_NEEDED_for_dynamic = entry->add_DT_NEEDED_for_dynamic; |
|
|
|
save_whole_archive = whole_archive; |
|
|
|
whole_archive = entry->whole_archive; |
|
|
|
input_flags.sysrooted = entry->flags.sysrooted; |
|
|
|
input_flags.add_DT_NEEDED_for_regular |
|
|
|
= entry->flags.add_DT_NEEDED_for_regular; |
|
|
|
input_flags.add_DT_NEEDED_for_dynamic |
|
|
|
= entry->flags.add_DT_NEEDED_for_dynamic; |
|
|
|
input_flags.whole_archive = entry->flags.whole_archive; |
|
|
|
input_flags.dynamic = entry->flags.dynamic; |
|
|
|
|
|
|
|
ldfile_assumed_script = TRUE; |
|
|
|
parser_input = input_script; |
|
|
|
/* We want to use the same -Bdynamic/-Bstatic as the one for
|
|
|
|
ENTRY. */ |
|
|
|
config.dynamic_link = entry->dynamic; |
|
|
|
yyparse (); |
|
|
|
ldfile_assumed_script = FALSE; |
|
|
|
|
|
|
|
ldlang_sysrooted_script = save_ldlang_sysrooted_script; |
|
|
|
add_DT_NEEDED_for_regular = save_add_DT_NEEDED_for_regular; |
|
|
|
add_DT_NEEDED_for_dynamic = save_add_DT_NEEDED_for_dynamic; |
|
|
|
whole_archive = save_whole_archive; |
|
|
|
/* missing_file is sticky. */ |
|
|
|
save_flags.missing_file |= input_flags.missing_file; |
|
|
|
input_flags = save_flags; |
|
|
|
pop_stat_ptr (); |
|
|
|
|
|
|
|
return TRUE; |
|
|
|
@ -2782,7 +2751,7 @@ load_symbols (lang_input_statement_type *entry, |
|
|
|
|
|
|
|
case bfd_object: |
|
|
|
#ifdef ENABLE_PLUGINS |
|
|
|
if (!entry->reload) |
|
|
|
if (!entry->flags.reload) |
|
|
|
#endif |
|
|
|
ldlang_add_file (entry); |
|
|
|
if (trace_files || trace_file_tries) |
|
|
|
@ -2792,7 +2761,7 @@ load_symbols (lang_input_statement_type *entry, |
|
|
|
case bfd_archive: |
|
|
|
check_excluded_libs (entry->the_bfd); |
|
|
|
|
|
|
|
if (entry->whole_archive) |
|
|
|
if (entry->flags.whole_archive) |
|
|
|
{ |
|
|
|
bfd *member = NULL; |
|
|
|
bfd_boolean loaded = TRUE; |
|
|
|
@ -2827,18 +2796,18 @@ load_symbols (lang_input_statement_type *entry, |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
entry->loaded = loaded; |
|
|
|
entry->flags.loaded = loaded; |
|
|
|
return loaded; |
|
|
|
} |
|
|
|
break; |
|
|
|
} |
|
|
|
|
|
|
|
if (bfd_link_add_symbols (entry->the_bfd, &link_info)) |
|
|
|
entry->loaded = TRUE; |
|
|
|
entry->flags.loaded = TRUE; |
|
|
|
else |
|
|
|
einfo (_("%F%B: could not read symbols: %E\n"), entry->the_bfd); |
|
|
|
|
|
|
|
return entry->loaded; |
|
|
|
return entry->flags.loaded; |
|
|
|
} |
|
|
|
|
|
|
|
/* Handle a wild statement. S->FILENAME or S->SECTION_LIST or both
|
|
|
|
@ -3022,7 +2991,7 @@ get_first_input_target (void) |
|
|
|
LANG_FOR_EACH_INPUT_STATEMENT (s) |
|
|
|
{ |
|
|
|
if (s->header.type == lang_input_statement_enum |
|
|
|
&& s->real) |
|
|
|
&& s->flags.real) |
|
|
|
{ |
|
|
|
ldfile_open_file (s); |
|
|
|
|
|
|
|
@ -3255,7 +3224,7 @@ open_input_bfds (lang_statement_union_type *s, enum open_bfd_mode mode) |
|
|
|
current_target = s->target_statement.target; |
|
|
|
break; |
|
|
|
case lang_input_statement_enum: |
|
|
|
if (s->input_statement.real) |
|
|
|
if (s->input_statement.flags.real) |
|
|
|
{ |
|
|
|
lang_statement_union_type **os_tail; |
|
|
|
lang_statement_list_type add; |
|
|
|
@ -3271,22 +3240,22 @@ open_input_bfds (lang_statement_union_type *s, enum open_bfd_mode mode) |
|
|
|
&& ((mode & OPEN_BFD_RESCAN) == 0 |
|
|
|
|| plugin_insert == NULL) |
|
|
|
#endif |
|
|
|
&& !s->input_statement.whole_archive |
|
|
|
&& s->input_statement.loaded |
|
|
|
&& !s->input_statement.flags.whole_archive |
|
|
|
&& s->input_statement.flags.loaded |
|
|
|
&& bfd_check_format (s->input_statement.the_bfd, |
|
|
|
bfd_archive)) |
|
|
|
s->input_statement.loaded = FALSE; |
|
|
|
s->input_statement.flags.loaded = FALSE; |
|
|
|
#ifdef ENABLE_PLUGINS |
|
|
|
/* When rescanning, reload --as-needed shared libs. */ |
|
|
|
else if ((mode & OPEN_BFD_RESCAN) != 0 |
|
|
|
&& plugin_insert == NULL |
|
|
|
&& s->input_statement.loaded |
|
|
|
&& s->input_statement.add_DT_NEEDED_for_regular |
|
|
|
&& s->input_statement.flags.loaded |
|
|
|
&& s->input_statement.flags.add_DT_NEEDED_for_regular |
|
|
|
&& ((s->input_statement.the_bfd->flags) & DYNAMIC) != 0 |
|
|
|
&& plugin_should_reload (s->input_statement.the_bfd)) |
|
|
|
{ |
|
|
|
s->input_statement.loaded = FALSE; |
|
|
|
s->input_statement.reload = TRUE; |
|
|
|
s->input_statement.flags.loaded = FALSE; |
|
|
|
s->input_statement.flags.reload = TRUE; |
|
|
|
} |
|
|
|
#endif |
|
|
|
|
|
|
|
@ -3337,7 +3306,7 @@ open_input_bfds (lang_statement_union_type *s, enum open_bfd_mode mode) |
|
|
|
} |
|
|
|
|
|
|
|
/* Exit if any of the files were missing. */ |
|
|
|
if (missing_file) |
|
|
|
if (input_flags.missing_file) |
|
|
|
einfo ("%F"); |
|
|
|
} |
|
|
|
|
|
|
|
@ -4648,7 +4617,7 @@ size_input_section |
|
|
|
lang_input_section_type *is = &((*this_ptr)->input_section); |
|
|
|
asection *i = is->section; |
|
|
|
|
|
|
|
if (!((lang_input_statement_type *) i->owner->usrdata)->just_syms_flag |
|
|
|
if (!((lang_input_statement_type *) i->owner->usrdata)->flags.just_syms |
|
|
|
&& (i->flags & SEC_EXCLUDE) == 0) |
|
|
|
{ |
|
|
|
bfd_size_type alignment_needed; |
|
|
|
@ -5819,7 +5788,7 @@ lang_check (void) |
|
|
|
{ |
|
|
|
#ifdef ENABLE_PLUGINS |
|
|
|
/* Don't check format of files claimed by plugin. */ |
|
|
|
if (file->input_statement.claimed) |
|
|
|
if (file->input_statement.flags.claimed) |
|
|
|
continue; |
|
|
|
#endif /* ENABLE_PLUGINS */ |
|
|
|
input_bfd = file->input_statement.the_bfd; |
|
|
|
@ -6022,7 +5991,7 @@ lang_place_orphans (void) |
|
|
|
/* This section of the file is not attached, root
|
|
|
|
around for a sensible place for it to go. */ |
|
|
|
|
|
|
|
if (file->just_syms_flag) |
|
|
|
if (file->flags.just_syms) |
|
|
|
bfd_link_just_syms (file->the_bfd, s, &link_info); |
|
|
|
else if ((s->flags & SEC_EXCLUDE) != 0) |
|
|
|
s->output_section = bfd_abs_section_ptr; |
|
|
|
@ -6334,7 +6303,7 @@ lang_gc_sections (void) |
|
|
|
{ |
|
|
|
asection *sec; |
|
|
|
#ifdef ENABLE_PLUGINS |
|
|
|
if (f->claimed) |
|
|
|
if (f->flags.claimed) |
|
|
|
continue; |
|
|
|
#endif |
|
|
|
for (sec = f->the_bfd->sections; sec != NULL; sec = sec->next) |
|
|
|
@ -6499,8 +6468,8 @@ find_replacements_insert_point (void) |
|
|
|
claim1 != NULL; |
|
|
|
claim1 = &claim1->next->input_statement) |
|
|
|
{ |
|
|
|
if (claim1->claimed) |
|
|
|
return claim1->claim_archive ? lastobject : claim1; |
|
|
|
if (claim1->flags.claimed) |
|
|
|
return claim1->flags.claim_archive ? lastobject : claim1; |
|
|
|
/* Update lastobject if this is a real object file. */ |
|
|
|
if (claim1->the_bfd && (claim1->the_bfd->my_archive == NULL)) |
|
|
|
lastobject = claim1; |
|
|
|
@ -6911,7 +6880,7 @@ lang_startup (const char *name) |
|
|
|
} |
|
|
|
first_file->filename = name; |
|
|
|
first_file->local_sym_name = name; |
|
|
|
first_file->real = TRUE; |
|
|
|
first_file->flags.real = TRUE; |
|
|
|
} |
|
|
|
|
|
|
|
void |
|
|
|
|