From 1f25b93bc6e10b314ccdc5c42583f77db1b33e2e Mon Sep 17 00:00:00 2001 From: Cary Coutant Date: Thu, 6 Feb 2014 17:12:50 -0800 Subject: 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 * 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. --- gold/archive.cc | 86 ++++++++++++++++++++++++++++++++------------------------- 1 file changed, 48 insertions(+), 38 deletions(-) (limited to 'gold/archive.cc') 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, -- cgit v1.1