From 78e03a33628ee801c93f006fa43ebb8cdb8dd243 Mon Sep 17 00:00:00 2001 From: "H.J. Lu" Date: Fri, 13 Oct 2017 05:02:19 -0700 Subject: [PATCH] gold: Ignore def/ref from a dynamic object for special symbols Since special symbol must be defined in a regular object, definition from a dynamic object should be ignored. If special symbol has the hidden or internal visibility, reference from a dynamic object should also be ignored. Also __start and __stop symbols in a dynamic object shouldn't be preempted. PR gold/22291 * layout.cc (Layout::define_section_symbols): Use STV_PROTECTED for __start and __stop symbols. * symtab.cc (Symbol_table::define_special_symbol): Add an argument, visibility. Ignore definition and reference from a dynamic object, depending on visibility. (Symbol_table::do_define_in_output_data): Pass visibility to define_special_symbol. (Symbol_table::do_define_in_output_segment): Likewise. (Symbol_table::do_define_as_constant): Likewise. (Symbol_table::add_undefined_symbol_from_command_line): Pass STV_DEFAULT to define_special_symbol. * symtab.h (Symbol_table::define_special_symbol): Add an argument, visibility. ixx --- gold/layout.cc | 4 ++-- gold/symtab.cc | 51 +++++++++++++++++++++++++++++++++++++++++---------- gold/symtab.h | 3 ++- 3 files changed, 45 insertions(+), 13 deletions(-) diff --git a/gold/layout.cc b/gold/layout.cc index 5f25faea55..c9dd823536 100644 --- a/gold/layout.cc +++ b/gold/layout.cc @@ -2228,7 +2228,7 @@ Layout::define_section_symbols(Symbol_table* symtab) 0, // symsize elfcpp::STT_NOTYPE, elfcpp::STB_GLOBAL, - elfcpp::STV_DEFAULT, + elfcpp::STV_PROTECTED, 0, // nonvis false, // offset_is_from_end true); // only_if_ref @@ -2241,7 +2241,7 @@ Layout::define_section_symbols(Symbol_table* symtab) 0, // symsize elfcpp::STT_NOTYPE, elfcpp::STB_GLOBAL, - elfcpp::STV_DEFAULT, + elfcpp::STV_PROTECTED, 0, // nonvis true, // offset_is_from_end true); // only_if_ref diff --git a/gold/symtab.cc b/gold/symtab.cc index 1555de6e5b..13ec5de277 100644 --- a/gold/symtab.cc +++ b/gold/symtab.cc @@ -1759,8 +1759,10 @@ template Sized_symbol* Symbol_table::define_special_symbol(const char** pname, const char** pversion, bool only_if_ref, + elfcpp::STV visibility, Sized_symbol** poldsym, - bool* resolve_oldsym, bool is_forced_local) + bool* resolve_oldsym, + bool is_forced_local) { *resolve_oldsym = false; *poldsym = NULL; @@ -1797,8 +1799,21 @@ Symbol_table::define_special_symbol(const char** pname, const char** pversion, oldsym = this->lookup(*pname, *pversion); if (oldsym == NULL && is_default_version) oldsym = this->lookup(*pname, NULL); - if (oldsym == NULL || !oldsym->is_undefined()) + if (oldsym == NULL) return NULL; + if (!oldsym->is_undefined()) + { + // Skip if the old definition is from a regular object. + if (!oldsym->is_from_dynobj()) + return NULL; + + // If the symbol has the hidden or internal visibility, ignore + // definition and reference from a dynamic object. + if ((visibility == elfcpp::STV_HIDDEN + || visibility == elfcpp::STV_INTERNAL) + && !oldsym->in_reg()) + return NULL; + } *pname = oldsym->name(); if (is_default_version) @@ -1973,7 +1988,9 @@ Symbol_table::do_define_in_output_data( { #if defined(HAVE_TARGET_32_BIG) || defined(HAVE_TARGET_64_BIG) sym = this->define_special_symbol(&name, &version, - only_if_ref, &oldsym, + only_if_ref, + visibility, + &oldsym, &resolve_oldsym, is_forced_local); #else @@ -1984,7 +2001,9 @@ Symbol_table::do_define_in_output_data( { #if defined(HAVE_TARGET_32_LITTLE) || defined(HAVE_TARGET_64_LITTLE) sym = this->define_special_symbol(&name, &version, - only_if_ref, &oldsym, + only_if_ref, + visibility, + &oldsym, &resolve_oldsym, is_forced_local); #else @@ -2092,7 +2111,9 @@ Symbol_table::do_define_in_output_segment( { #if defined(HAVE_TARGET_32_BIG) || defined(HAVE_TARGET_64_BIG) sym = this->define_special_symbol(&name, &version, - only_if_ref, &oldsym, + only_if_ref, + visibility, + &oldsym, &resolve_oldsym, is_forced_local); #else @@ -2103,7 +2124,9 @@ Symbol_table::do_define_in_output_segment( { #if defined(HAVE_TARGET_32_LITTLE) || defined(HAVE_TARGET_64_LITTLE) sym = this->define_special_symbol(&name, &version, - only_if_ref, &oldsym, + only_if_ref, + visibility, + &oldsym, &resolve_oldsym, is_forced_local); #else @@ -2209,7 +2232,9 @@ Symbol_table::do_define_as_constant( { #if defined(HAVE_TARGET_32_BIG) || defined(HAVE_TARGET_64_BIG) sym = this->define_special_symbol(&name, &version, - only_if_ref, &oldsym, + only_if_ref, + visibility, + &oldsym, &resolve_oldsym, is_forced_local); #else @@ -2220,7 +2245,9 @@ Symbol_table::do_define_as_constant( { #if defined(HAVE_TARGET_32_LITTLE) || defined(HAVE_TARGET_64_LITTLE) sym = this->define_special_symbol(&name, &version, - only_if_ref, &oldsym, + only_if_ref, + visibility, + &oldsym, &resolve_oldsym, is_forced_local); #else @@ -2447,7 +2474,9 @@ Symbol_table::add_undefined_symbol_from_command_line(const char* name) { #if defined(HAVE_TARGET_32_BIG) || defined(HAVE_TARGET_64_BIG) sym = this->define_special_symbol(&name, &version, - false, &oldsym, + false, + elfcpp::STV_DEFAULT, + &oldsym, &resolve_oldsym, false); #else @@ -2458,7 +2487,9 @@ Symbol_table::add_undefined_symbol_from_command_line(const char* name) { #if defined(HAVE_TARGET_32_LITTLE) || defined(HAVE_TARGET_64_LITTLE) sym = this->define_special_symbol(&name, &version, - false, &oldsym, + false, + elfcpp::STV_DEFAULT, + &oldsym, &resolve_oldsym, false); #else diff --git a/gold/symtab.h b/gold/symtab.h index a67d5eb90d..edf1c1729c 100644 --- a/gold/symtab.h +++ b/gold/symtab.h @@ -1830,7 +1830,8 @@ class Symbol_table template Sized_symbol* define_special_symbol(const char** pname, const char** pversion, - bool only_if_ref, Sized_symbol** poldsym, + bool only_if_ref, elfcpp::STV visibility, + Sized_symbol** poldsym, bool* resolve_oldsym, bool is_forced_local); // Define a symbol in an Output_data, sized version. -- 2.13.6