This is the mail archive of the binutils-cvs@sourceware.org mailing list for the binutils project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[binutils-gdb] Improve COFF/PE linker garbage collection by preventing the removal of sections containing exported


https://sourceware.org/git/gitweb.cgi?p=binutils-gdb.git;h=4153b6dbb0f38a16fd5b583761aa811212fbb9a5

commit 4153b6dbb0f38a16fd5b583761aa811212fbb9a5
Author: Nick Clifton <nickc@redhat.com>
Date:   Tue Mar 22 12:25:08 2016 +0000

    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.

Diff:
---
 ld/ChangeLog                 | 13 ++++++++++++
 ld/ldlang.c                  | 49 ++++++++++++++++++++++----------------------
 ld/ldlang.h                  |  3 +++
 ld/pe-dll.c                  |  3 +++
 ld/testsuite/ld-pe/pr19803.d | 12 ++++-------
 ld/testsuite/ld-pe/pr19803.s |  1 -
 6 files changed, 47 insertions(+), 34 deletions(-)

diff --git a/ld/ChangeLog b/ld/ChangeLog
index 92a71b7..0e16f80 100644
--- a/ld/ChangeLog
+++ b/ld/ChangeLog
@@ -1,5 +1,18 @@
 2016-03-22  Nick Clifton  <nickc@redhat.com>
 
+	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.
+
+2016-03-22  Nick Clifton  <nickc@redhat.com>
+
 	* configure: Regenerate.
 
 2016-03-21  Nick Clifton  <nickc@redhat.com>
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)
diff --git a/ld/ldlang.h b/ld/ldlang.h
index c3d1185..65d768b 100644
--- a/ld/ldlang.h
+++ b/ld/ldlang.h
@@ -693,4 +693,7 @@ lang_ld_feature (char *);
 extern void
 lang_print_memory_usage (void);
 
+extern void
+lang_add_gc_name (const char *);
+
 #endif
diff --git a/ld/pe-dll.c b/ld/pe-dll.c
index a2792e8..a280647 100644
--- a/ld/pe-dll.c
+++ b/ld/pe-dll.c
@@ -897,6 +897,9 @@ process_def_file_and_drectve (bfd *abfd ATTRIBUTE_UNUSED, struct bfd_link_info *
       char *int_name = pe_def_file->exports[i].internal_name;
       char *name;
 
+      /* PR 19803: Make sure that any exported symbol does not get garbage collected.  */
+      lang_add_gc_name (int_name);
+
       name = xmalloc (strlen (int_name) + 2);
       if (pe_details->underscored && int_name[0] != '@')
 	{
diff --git a/ld/testsuite/ld-pe/pr19803.d b/ld/testsuite/ld-pe/pr19803.d
index 1fc6daf..d8d0c55 100644
--- a/ld/testsuite/ld-pe/pr19803.d
+++ b/ld/testsuite/ld-pe/pr19803.d
@@ -1,17 +1,13 @@
 #ld: -shared --out-implib dx.dll.a --gc-sections
 #objdump: --syms
-#notarget: mcore-* arm-epoc-pe
+#notarget: mcore-*
 #
-# Check that the target specific entry symbol _DllMainCRTStartup is still
+# The MCORE-PE target does not support -shared.
+#
+# Check that the target specific entry symbol *Startup 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.s b/ld/testsuite/ld-pe/pr19803.s
index 290a698..cabb87e 100644
--- a/ld/testsuite/ld-pe/pr19803.s
+++ b/ld/testsuite/ld-pe/pr19803.s
@@ -8,7 +8,6 @@ DllMainCRTStartup:
 	nop
 
 	.section .rdata,"dr"
-        .globl  _testval
 _testval:
         .long   1
         .long   2


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]