diff options
Diffstat (limited to 'binutils-2.25/gold/symtab.cc')
-rw-r--r-- | binutils-2.25/gold/symtab.cc | 35 |
1 files changed, 26 insertions, 9 deletions
diff --git a/binutils-2.25/gold/symtab.cc b/binutils-2.25/gold/symtab.cc index 045327ac..0c8cf376 100644 --- a/binutils-2.25/gold/symtab.cc +++ b/binutils-2.25/gold/symtab.cc @@ -1,6 +1,6 @@ // symtab.cc -- the gold symbol table -// Copyright (C) 2006-2015 Free Software Foundation, Inc. +// Copyright (C) 2006-2014 Free Software Foundation, Inc. // Written by Ian Lance Taylor <iant@google.com>. // This file is part of gold. @@ -419,9 +419,13 @@ Symbol::should_add_dynsym_entry(Symbol_table* symtab) const } // If exporting all symbols or building a shared library, + // or the symbol should be globally unique (GNU_UNIQUE), // and the symbol is defined in a regular object and is // externally visible, we need to add it. - if ((parameters->options().export_dynamic() || parameters->options().shared()) + if ((parameters->options().export_dynamic() + || parameters->options().shared() + || (parameters->options().gnu_unique() + && this->binding() == elfcpp::STB_GNU_UNIQUE)) && !this->is_from_dynobj() && !this->is_undefined() && this->is_externally_visible()) @@ -437,9 +441,12 @@ bool Symbol::final_value_is_known() const { // If we are not generating an executable, then no final values are - // known, since they will change at runtime. - if (parameters->options().output_is_position_independent() - || parameters->options().relocatable()) + // known, since they will change at runtime, with the exception of + // TLS symbols in a position-independent executable. + if ((parameters->options().output_is_position_independent() + || parameters->options().relocatable()) + && !(this->type() == elfcpp::STT_TLS + && parameters->options().pie())) return false; // If the symbol is not from an object file, and is not undefined, @@ -2913,6 +2920,13 @@ Symbol_table::sized_write_globals(const Stringpool* sympool, typename elfcpp::Elf_types<size>::Elf_Addr dynsym_value = sym_value; elfcpp::STB binding = sym->binding(); + // If --weak-unresolved-symbols is set, change binding of unresolved + // global symbols to STB_WEAK. + if (parameters->options().weak_unresolved_symbols() + && binding == elfcpp::STB_GLOBAL + && sym->is_undefined()) + binding = elfcpp::STB_WEAK; + // If --no-gnu-unique is set, change STB_GNU_UNIQUE to STB_GLOBAL. if (binding == elfcpp::STB_GNU_UNIQUE && !parameters->options().gnu_unique()) @@ -3336,8 +3350,11 @@ Symbol_table::detect_odr_violations(const Task* task, first_object_name = locs->object->name(); first_object_linenos = this->linenos_from_loc(task, *locs); } + if (first_object_linenos.empty()) + continue; // Sort by Odr_violation_compare to make std::set_intersection work. + std::string first_object_canonical_result = first_object_linenos.back(); std::sort(first_object_linenos.begin(), first_object_linenos.end(), Odr_violation_compare()); @@ -3349,6 +3366,8 @@ Symbol_table::detect_odr_violations(const Task* task, if (linenos.empty()) continue; // Sort by Odr_violation_compare to make std::set_intersection work. + gold_assert(!linenos.empty()); + std::string second_object_canonical_result = linenos.back(); std::sort(linenos.begin(), linenos.end(), Odr_violation_compare()); Check_intersection intersection_result = @@ -3367,13 +3386,11 @@ Symbol_table::detect_odr_violations(const Task* task, // which may not be the location we expect to intersect // with another definition. We could print the whole // set of locations, but that seems too verbose. - gold_assert(!first_object_linenos.empty()); - gold_assert(!linenos.empty()); fprintf(stderr, _(" %s from %s\n"), - first_object_linenos[0].c_str(), + first_object_canonical_result.c_str(), first_object_name.c_str()); fprintf(stderr, _(" %s from %s\n"), - linenos[0].c_str(), + second_object_canonical_result.c_str(), locs->object->name().c_str()); // Only print one broken pair, to avoid needing to // compare against a list of the disjoint definition |