diff options
author | Nick Clifton <nickc@redhat.com> | 2016-03-22 12:25:08 +0000 |
---|---|---|
committer | Nick Clifton <nickc@redhat.com> | 2016-03-22 12:25:08 +0000 |
commit | 4153b6dbb0f38a16fd5b583761aa811212fbb9a5 (patch) | |
tree | d658cb18fecbd0a8691b62fed5924d583108b3a9 /ld/ldlang.c | |
parent | a97fbc7e3ca781b8d95ed8591c6ee65f2d8a798a (diff) | |
download | gdb-4153b6dbb0f38a16fd5b583761aa811212fbb9a5.zip gdb-4153b6dbb0f38a16fd5b583761aa811212fbb9a5.tar.gz gdb-4153b6dbb0f38a16fd5b583761aa811212fbb9a5.tar.bz2 |
Improve COFF/PE linker garbage collection by preventing the removal of sections containing exported symbols.
PR ld/19803
* ldlang.c (lang_add_gc_name): New function. Adds the provided
symbol name to the list of gc symbols.
(lang_process): Call lang_add_gc_name with entry_symbol_default if
entry_symbol.name is NULL. Use lang_add_gc_name to add the init
and fini function names.
* pe-dll.c (process_def_file_and_drectve): Add exported names to
the gc symbol list.
* testsuite/ld-pe/pr19803.s: Do not export _testval symbol.
* testsuite/ld-pe/pr19803.d: Tweak expected output.
Diffstat (limited to 'ld/ldlang.c')
-rw-r--r-- | ld/ldlang.c | 49 |
1 files changed, 24 insertions, 25 deletions
diff --git a/ld/ldlang.c b/ld/ldlang.c index e6cc424..2efab24 100644 --- a/ld/ldlang.c +++ b/ld/ldlang.c @@ -6699,6 +6699,23 @@ lang_list_remove_tail (lang_statement_list_type *destlist, } #endif /* ENABLE_PLUGINS */ +/* Add NAME to the list of garbage collection entry points. */ + +void +lang_add_gc_name (const char * name) +{ + struct bfd_sym_chain *sym; + + if (name == NULL) + return; + + sym = (struct bfd_sym_chain *) stat_alloc (sizeof (*sym)); + + sym->next = link_info.gc_sym_list; + sym->name = name; + link_info.gc_sym_list = sym; +} + void lang_process (void) { @@ -6781,6 +6798,9 @@ lang_process (void) } #endif /* ENABLE_PLUGINS */ + /* Make sure that nobody has tried to add a symbol to this list before now. */ + ASSERT (link_info.gc_sym_list == NULL); + link_info.gc_sym_list = &entry_symbol; if (entry_symbol.name == NULL) @@ -6790,37 +6810,16 @@ lang_process (void) /* 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. + provided an entry symbol via a call to lang_default_entry(). 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; - } + lang_add_gc_name (entry_symbol_default); } - if (link_info.init_function != NULL) - { - struct bfd_sym_chain *sym - = (struct bfd_sym_chain *) stat_alloc (sizeof (*sym)); - sym->next = link_info.gc_sym_list; - sym->name = link_info.init_function; - link_info.gc_sym_list = sym; - } - if (link_info.fini_function != NULL) - { - struct bfd_sym_chain *sym - = (struct bfd_sym_chain *) stat_alloc (sizeof (*sym)); - sym->next = link_info.gc_sym_list; - sym->name = link_info.fini_function; - link_info.gc_sym_list = sym; - } + lang_add_gc_name (link_info.init_function); + lang_add_gc_name (link_info.fini_function); ldemul_after_open (); if (config.map_file != NULL) |