aboutsummaryrefslogtreecommitdiff
path: root/ld
diff options
context:
space:
mode:
authorNick Clifton <nickc@redhat.com>2016-03-22 12:25:08 +0000
committerNick Clifton <nickc@redhat.com>2016-03-22 12:25:08 +0000
commit4153b6dbb0f38a16fd5b583761aa811212fbb9a5 (patch)
treed658cb18fecbd0a8691b62fed5924d583108b3a9 /ld
parenta97fbc7e3ca781b8d95ed8591c6ee65f2d8a798a (diff)
downloadgdb-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')
-rw-r--r--ld/ChangeLog13
-rw-r--r--ld/ldlang.c49
-rw-r--r--ld/ldlang.h3
-rw-r--r--ld/pe-dll.c3
-rw-r--r--ld/testsuite/ld-pe/pr19803.d12
-rw-r--r--ld/testsuite/ld-pe/pr19803.s1
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