aboutsummaryrefslogtreecommitdiff
path: root/gold/symtab.cc
diff options
context:
space:
mode:
authorCary Coutant <ccoutant@gmail.com>2018-04-23 09:27:35 -0700
committerCary Coutant <ccoutant@gmail.com>2018-04-24 13:51:24 -0700
commit890d155592e66dc01fc4a9affba806c4e9fc36ba (patch)
tree0ccfa6f963c937ec8f5648ecb9d401ae676c0778 /gold/symtab.cc
parentf67c0c9171508672167b6868c67211571421a1c6 (diff)
downloadfsf-binutils-gdb-890d155592e66dc01fc4a9affba806c4e9fc36ba.zip
fsf-binutils-gdb-890d155592e66dc01fc4a9affba806c4e9fc36ba.tar.gz
fsf-binutils-gdb-890d155592e66dc01fc4a9affba806c4e9fc36ba.tar.bz2
Fix internal error caused by conflicting default version definitions.
gold/ PR gold/16504 * dynobj.cc (Versions::symbol_section_contents): Don't set VERSYM_HIDDEN flag for undefined symbols. * symtab.cc (Symbol_table::add_from_object): Don't override default version definition with a different default version. * symtab.h (Symbol::from_dyn): New method. * testsuite/plugin_test.c (struct sym_info): Add ver field. (claim_file_hook): Pass symbol version to plugin API. (parse_readelf_line): Parse symbol version. * testsuite/Makefile.am (ver_test_pr16504): New test case. * testsuite/Makefile.in: Regenerate. * testsuite/ver_test_pr16504.sh: New test script. * testsuite/ver_test_pr16504_a.c: New source file. * testsuite/ver_test_pr16504_a.script: New version script. * testsuite/ver_test_pr16504_b.c: New source file. * testsuite/ver_test_pr16504_b.script: New version script.
Diffstat (limited to 'gold/symtab.cc')
-rw-r--r--gold/symtab.cc47
1 files changed, 36 insertions, 11 deletions
diff --git a/gold/symtab.cc b/gold/symtab.cc
index 34551ac..238834d 100644
--- a/gold/symtab.cc
+++ b/gold/symtab.cc
@@ -989,7 +989,7 @@ Symbol_table::add_from_object(Object* object,
// ins.first->second: the value (Symbol*).
// ins.second: true if new entry was inserted, false if not.
- Sized_symbol<size>* ret;
+ Sized_symbol<size>* ret = NULL;
bool was_undefined_in_reg;
bool was_common;
if (!ins.second)
@@ -1049,17 +1049,42 @@ Symbol_table::add_from_object(Object* object,
// it, then change it to NAME/VERSION.
ret = this->get_sized_symbol<size>(insdefault.first->second);
- was_undefined_in_reg = ret->is_undefined() && ret->in_reg();
- // Commons from plugins are just placeholders.
- was_common = ret->is_common() && ret->object()->pluginobj() == NULL;
-
- this->resolve(ret, sym, st_shndx, is_ordinary, orig_st_shndx, object,
- version, is_default_version);
- if (parameters->options().gc_sections())
- this->gc_mark_dyn_syms(ret);
- ins.first->second = ret;
+ // If the existing symbol already has a version,
+ // don't override it with the new symbol.
+ // This should only happen when the new symbol
+ // is from a shared library.
+ if (ret->version() != NULL)
+ {
+ if (!object->is_dynamic())
+ {
+ gold_warning(_("%s: conflicting default version definition"
+ " for %s@@%s"),
+ object->name().c_str(), name, version);
+ if (ret->source() == Symbol::FROM_OBJECT)
+ gold_info(_("%s: %s: previous definition of %s@@%s here"),
+ program_name,
+ ret->object()->name().c_str(),
+ name, ret->version());
+ }
+ ret = NULL;
+ is_default_version = false;
+ }
+ else
+ {
+ was_undefined_in_reg = ret->is_undefined() && ret->in_reg();
+ // Commons from plugins are just placeholders.
+ was_common = (ret->is_common()
+ && ret->object()->pluginobj() == NULL);
+
+ this->resolve(ret, sym, st_shndx, is_ordinary, orig_st_shndx,
+ object, version, is_default_version);
+ if (parameters->options().gc_sections())
+ this->gc_mark_dyn_syms(ret);
+ ins.first->second = ret;
+ }
}
- else
+
+ if (ret == NULL)
{
was_undefined_in_reg = false;
was_common = false;