diff options
Diffstat (limited to 'ld/ldlang.c')
-rw-r--r-- | ld/ldlang.c | 26 |
1 files changed, 23 insertions, 3 deletions
diff --git a/ld/ldlang.c b/ld/ldlang.c index 7b74e24..e6cc424 100644 --- a/ld/ldlang.c +++ b/ld/ldlang.c @@ -6477,7 +6477,6 @@ static void lang_gc_sections (void) { /* Keep all sections so marked in the link script. */ - lang_gc_sections_1 (statement_list.head); /* SEC_EXCLUDE is ignored when doing a relocatable link, except in @@ -6783,9 +6782,30 @@ lang_process (void) #endif /* ENABLE_PLUGINS */ link_info.gc_sym_list = &entry_symbol; + if (entry_symbol.name == NULL) - link_info.gc_sym_list = ldlang_undef_chain_list_head; - if (link_info.init_function != NULL) + { + link_info.gc_sym_list = ldlang_undef_chain_list_head; + + /* entry_symbol is normally initialied by a ENTRY definition in the + linker script or the -e command line option. But if neither of + these have been used, the target specific backend may still have + provided an entry symbol via a call to lang_default_entry()o. + Unfortunately this value will not be processed until lang_end() + is called, long after this function has finished. So detect this + case here and add the target's entry symbol to the list of starting + points for garbage collection resolution. */ + if (entry_symbol_default != NULL) + { + struct bfd_sym_chain *sym + = (struct bfd_sym_chain *) stat_alloc (sizeof (*sym)); + sym->next = link_info.gc_sym_list; + sym->name = entry_symbol_default; + link_info.gc_sym_list = sym; + } + } + + if (link_info.init_function != NULL) { struct bfd_sym_chain *sym = (struct bfd_sym_chain *) stat_alloc (sizeof (*sym)); |