aboutsummaryrefslogtreecommitdiff
path: root/gold/archive.cc
diff options
context:
space:
mode:
authorCary Coutant <ccoutant@google.com>2014-02-06 17:12:50 -0800
committerCary Coutant <ccoutant@google.com>2014-02-06 17:15:02 -0800
commit1f25b93bc6e10b314ccdc5c42583f77db1b33e2e (patch)
treed7141deb29a5c81b6728666967f0af067faf42f8 /gold/archive.cc
parent699e9b8780835c321da32a6c32cd6dd56fcd6d54 (diff)
downloadfsf-binutils-gdb-1f25b93bc6e10b314ccdc5c42583f77db1b33e2e.zip
fsf-binutils-gdb-1f25b93bc6e10b314ccdc5c42583f77db1b33e2e.tar.gz
fsf-binutils-gdb-1f25b93bc6e10b314ccdc5c42583f77db1b33e2e.tar.bz2
Fix problem where -u is ignored when a weak undef is seen.
When the linker has a weak undefined symbol, it normally does not select an archive library member just to satisfy the reference. If the same symbol is also listed in a -u option, however, we should select the archive library member. This patch reorders the code in Library_base::should_include_member so that the additional checks are performed in the case of a weak undef. gold/ 2014-02-06 Cary Coutant <ccoutant@google.com> * archive.cc (Library_base::should_include_member): Reorder code to check for -u option if a weak undef has already been seen. * testsuite/Makefile.am (weak_undef_test_2): New test case. * testsuite/Makefile.in: Regenerate. * testsuite/weak_undef_file3.cc: New file. * testsuite/weak_undef_file4.cc: New file. * testsuite/weak_undef_test_2.cc: New file.
Diffstat (limited to 'gold/archive.cc')
-rw-r--r--gold/archive.cc86
1 files changed, 48 insertions, 38 deletions
diff --git a/gold/archive.cc b/gold/archive.cc
index 53d88a2..b52ebd3 100644
--- a/gold/archive.cc
+++ b/gold/archive.cc
@@ -97,46 +97,56 @@ Library_base::should_include_member(Symbol_table* symtab, Layout* layout,
*symp = sym;
- if (sym == NULL)
+ if (sym != NULL)
{
- // Check whether the symbol was named in a -u option.
- if (parameters->options().is_undefined(sym_name))
- {
- *why = "-u ";
- *why += sym_name;
- }
- else if (parameters->options().is_export_dynamic_symbol(sym_name))
- {
- *why = "--export-dynamic-symbol ";
- *why += sym_name;
- }
- else if (layout->script_options()->is_referenced(sym_name))
- {
- size_t alc = 100 + strlen(sym_name);
- char* buf = new char[alc];
- snprintf(buf, alc, _("script or expression reference to %s"),
- sym_name);
- *why = buf;
- delete[] buf;
- }
- else if (strcmp(sym_name, parameters->entry()) == 0)
- {
- *why = "entry symbol ";
- *why += sym_name;
- }
- else
- return Library_base::SHOULD_INCLUDE_UNKNOWN;
+ if (!sym->is_undefined())
+ return Library_base::SHOULD_INCLUDE_NO;
+
+ // PR 12001: Do not include an archive when the undefined
+ // symbol has actually been defined on the command line.
+ if (layout->script_options()->is_pending_assignment(sym_name))
+ return Library_base::SHOULD_INCLUDE_NO;
+
+ // If the symbol is weak undefined, we still need to check
+ // for other reasons (like a -u option).
+ if (sym->binding() != elfcpp::STB_WEAK)
+ return Library_base::SHOULD_INCLUDE_YES;
+ }
+
+ // Check whether the symbol was named in a -u option.
+ if (parameters->options().is_undefined(sym_name))
+ {
+ *why = "-u ";
+ *why += sym_name;
+ return Library_base::SHOULD_INCLUDE_YES;
+ }
+
+ if (parameters->options().is_export_dynamic_symbol(sym_name))
+ {
+ *why = "--export-dynamic-symbol ";
+ *why += sym_name;
+ return Library_base::SHOULD_INCLUDE_YES;
}
- else if (!sym->is_undefined())
- return Library_base::SHOULD_INCLUDE_NO;
- // PR 12001: Do not include an archive when the undefined
- // symbol has actually been defined on the command line.
- else if (layout->script_options()->is_pending_assignment(sym_name))
- return Library_base::SHOULD_INCLUDE_NO;
- else if (sym->binding() == elfcpp::STB_WEAK)
- return Library_base::SHOULD_INCLUDE_UNKNOWN;
-
- return Library_base::SHOULD_INCLUDE_YES;
+
+ if (layout->script_options()->is_referenced(sym_name))
+ {
+ size_t alc = 100 + strlen(sym_name);
+ char* buf = new char[alc];
+ snprintf(buf, alc, _("script or expression reference to %s"),
+ sym_name);
+ *why = buf;
+ delete[] buf;
+ return Library_base::SHOULD_INCLUDE_YES;
+ }
+
+ if (strcmp(sym_name, parameters->entry()) == 0)
+ {
+ *why = "entry symbol ";
+ *why += sym_name;
+ return Library_base::SHOULD_INCLUDE_YES;
+ }
+
+ return Library_base::SHOULD_INCLUDE_UNKNOWN;
}
// The header of an entry in the archive. This is all readable text,