diff options
author | Cary Coutant <ccoutant@gmail.com> | 2018-04-23 09:27:35 -0700 |
---|---|---|
committer | Cary Coutant <ccoutant@gmail.com> | 2018-04-24 13:51:24 -0700 |
commit | 890d155592e66dc01fc4a9affba806c4e9fc36ba (patch) | |
tree | 0ccfa6f963c937ec8f5648ecb9d401ae676c0778 /gold/symtab.cc | |
parent | f67c0c9171508672167b6868c67211571421a1c6 (diff) | |
download | fsf-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.cc | 47 |
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; |