diff options
author | Cary Coutant <ccoutant@google.com> | 2014-02-06 17:12:50 -0800 |
---|---|---|
committer | Cary Coutant <ccoutant@google.com> | 2014-02-06 17:15:02 -0800 |
commit | 1f25b93bc6e10b314ccdc5c42583f77db1b33e2e (patch) | |
tree | d7141deb29a5c81b6728666967f0af067faf42f8 /gold/archive.cc | |
parent | 699e9b8780835c321da32a6c32cd6dd56fcd6d54 (diff) | |
download | gdb-1f25b93bc6e10b314ccdc5c42583f77db1b33e2e.zip gdb-1f25b93bc6e10b314ccdc5c42583f77db1b33e2e.tar.gz 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.cc | 86 |
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, |