From 41f46ed9fea1a066de95b6a85c56393beef0b8b8 Mon Sep 17 00:00:00 2001 From: Senthil Kumar Selvaraj Date: Fri, 18 Mar 2016 09:51:47 +0000 Subject: [PATCH] Fix possible failure in the AVR linker tests. * ld-avr/gc-section-debugline.d: Relax regex check for CU. --- ld/ChangeLog | 4 +++ ld/emultempl/pe.em | 1 - ld/ldlang.c | 26 +++++++++++++-- ld/pe-dll.c | 38 ++++++++++++++++++++++ ld/testsuite/ld-avr/gc-section-debugline.d | 2 +- ld/testsuite/ld-pe/pe.exp | 14 ++++++++ ld/testsuite/ld-pe/pr19803.d | 17 ++++++++++ ld/testsuite/ld-pe/pr19803.e | 3 ++ ld/testsuite/ld-pe/pr19803.s | 14 ++++++++ 9 files changed, 114 insertions(+), 5 deletions(-) create mode 100644 ld/testsuite/ld-pe/pr19803.d create mode 100644 ld/testsuite/ld-pe/pr19803.e create mode 100644 ld/testsuite/ld-pe/pr19803.s diff --git a/ld/ChangeLog b/ld/ChangeLog index 04b484cc4ed..401226bc54b 100644 --- a/ld/ChangeLog +++ b/ld/ChangeLog @@ -1,3 +1,7 @@ +2016-03-18 Senthil Kumar Selvaraj + + * ld-avr/gc-section-debugline.d: Relax regex check for CU. + 2016-03-15 H.J. Lu PR ld/19827 diff --git a/ld/emultempl/pe.em b/ld/emultempl/pe.em index 2b78536df89..bf146f69a9c 100644 --- a/ld/emultempl/pe.em +++ b/ld/emultempl/pe.em @@ -563,7 +563,6 @@ set_entry_point (void) } else { - for (i = 0; v[i].entry; i++) if (v[i].value == pe_subsystem) break; diff --git a/ld/ldlang.c b/ld/ldlang.c index 7b74e2483f6..e6cc4244da8 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)); diff --git a/ld/pe-dll.c b/ld/pe-dll.c index 14f963b2745..ccdbed0d23a 100644 --- a/ld/pe-dll.c +++ b/ld/pe-dll.c @@ -895,6 +895,7 @@ process_def_file_and_drectve (bfd *abfd ATTRIBUTE_UNUSED, struct bfd_link_info * for (i = 0; i < NE; i++) { char *name; + name = xmalloc (strlen (pe_def_file->exports[i].internal_name) + 2); if (pe_details->underscored && (*pe_def_file->exports[i].internal_name != '@')) @@ -2790,7 +2791,44 @@ pe_dll_generate_implib (def_file *def, const char *impfilename, struct bfd_link_ /* Don't add PRIVATE entries to import lib. */ if (pe_def_file->exports[i].flag_private) continue; + def->exports[i].internal_name = def->exports[i].name; + + /* PR 19803: If a symbol has been discard due to garbage + collection then do not create any exports for it. */ + { + struct coff_link_hash_entry *h; + + h = coff_link_hash_lookup (coff_hash_table (info), internal, + FALSE, FALSE, FALSE); + if (h != NULL + /* If the symbol is hidden and undefined then it + has been swept up by garbage collection. */ + && h->symbol_class == C_HIDDEN + && h->root.u.def.section == bfd_und_section_ptr) + continue; + + /* If necessary, check with an underscore prefix as well. */ + if (pe_details->underscored && internal[0] != '@') + { + char *name; + + name = xmalloc (strlen (internal) + 2); + sprintf (name, "_%s", internal); + + h = coff_link_hash_lookup (coff_hash_table (info), name, + FALSE, FALSE, FALSE); + free (name); + + if (h != NULL + /* If the symbol is hidden and undefined then it + has been swept up by garbage collection. */ + && h->symbol_class == C_HIDDEN + && h->root.u.def.section == bfd_und_section_ptr) + continue; + } + } + n = make_one (def->exports + i, outarch, ! (def->exports + i)->flag_data); n->archive_next = head; diff --git a/ld/testsuite/ld-avr/gc-section-debugline.d b/ld/testsuite/ld-avr/gc-section-debugline.d index e98ff6c0cfa..f8c07de6a4a 100644 --- a/ld/testsuite/ld-avr/gc-section-debugline.d +++ b/ld/testsuite/ld-avr/gc-section-debugline.d @@ -9,7 +9,7 @@ Decoded dump of debug contents of section .debug_line: -CU: .*: +.*: File name Line number Starting address per-function-debugline.s 39 0 diff --git a/ld/testsuite/ld-pe/pe.exp b/ld/testsuite/ld-pe/pe.exp index 622caed2dab..a31f6e7fd74 100644 --- a/ld/testsuite/ld-pe/pe.exp +++ b/ld/testsuite/ld-pe/pe.exp @@ -76,6 +76,20 @@ run_dump_test "longsecn-5" run_dump_test "orphan" run_dump_test "orphan_nu" +run_dump_test "pr19803" +set pr19803_dll { + { "PR 19803: not exporting swept symbols" + "-shared --out-implib dx.dll --gc-sections" + "" "" {pr19803.s} + {{objdump "--syms dx.dll" pr19803.e}} + "a.exe"} +} +# This test is *supposed* to fail. If the symbol defined in pr19803.e is +# found then it was not stripped from the export dll, despite the fact that +# it (should have been) garbage collected from the executable. +setup_xfail *-*-* +run_ld_link_tests $pr19803_dll + if {[istarget x86_64-*-mingw*] } { run_dump_test "cfi" } elseif {[istarget i*86-*-cygwin*] || [istarget i*86-*-mingw*] } { diff --git a/ld/testsuite/ld-pe/pr19803.d b/ld/testsuite/ld-pe/pr19803.d new file mode 100644 index 00000000000..1fc6daf17f6 --- /dev/null +++ b/ld/testsuite/ld-pe/pr19803.d @@ -0,0 +1,17 @@ +#ld: -shared --out-implib dx.dll.a --gc-sections +#objdump: --syms +#notarget: mcore-* arm-epoc-pe +# +# Check that the target specific entry symbol _DllMainCRTStartup is still +# a defined (sec > 0), public (scl == 2) symbol, even after garbage +# collection. +# +# Check that the symbol _testval is undefined (sec == 0) and hidden +# (scl == 106) in the output. It should have been changed to this state when +# garbage collection was performed. + +#... +.*\(sec 0\)\(fl 0x00\)\(ty 0\)\(scl 106\) \(nx 0\) 0x0+000 _testval +#... +.*\(sec 1\)\(fl 0x00\)\(ty 0\)\(scl 2\) \(nx 0\) 0x0+000 .*Startup.* +#pass diff --git a/ld/testsuite/ld-pe/pr19803.e b/ld/testsuite/ld-pe/pr19803.e new file mode 100644 index 00000000000..a2f816221fa --- /dev/null +++ b/ld/testsuite/ld-pe/pr19803.e @@ -0,0 +1,3 @@ +#... +.*__imp__testval +#pass diff --git a/ld/testsuite/ld-pe/pr19803.s b/ld/testsuite/ld-pe/pr19803.s new file mode 100644 index 00000000000..290a698e9c2 --- /dev/null +++ b/ld/testsuite/ld-pe/pr19803.s @@ -0,0 +1,14 @@ + .text + .globl "_DllMainCRTStartup@12" +"_DllMainCRTStartup@12": + .globl _DllMainCRTStartup +_DllMainCRTStartup: + .globl DllMainCRTStartup +DllMainCRTStartup: + nop + + .section .rdata,"dr" + .globl _testval +_testval: + .long 1 + .long 2 -- 2.30.2