diff options
author | H.J. Lu <hjl.tools@gmail.com> | 2017-11-08 15:56:54 -0800 |
---|---|---|
committer | H.J. Lu <hjl.tools@gmail.com> | 2017-11-08 16:02:50 -0800 |
commit | dc8d2d90da3f191ae0461900ab98e3b29cc2b280 (patch) | |
tree | 810c9e619488f444ac0079866dc15714da1a2d9f | |
parent | cb1a122cce8a7eefe1025d8d189c52f96da6138f (diff) | |
download | gdb-dc8d2d90da3f191ae0461900ab98e3b29cc2b280.zip gdb-dc8d2d90da3f191ae0461900ab98e3b29cc2b280.tar.gz gdb-dc8d2d90da3f191ae0461900ab98e3b29cc2b280.tar.bz2 |
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.
-rw-r--r-- | gold/ChangeLog | 17 | ||||
-rw-r--r-- | gold/layout.cc | 4 | ||||
-rw-r--r-- | gold/symtab.cc | 48 | ||||
-rw-r--r-- | gold/symtab.h | 3 |
4 files changed, 60 insertions, 12 deletions
diff --git a/gold/ChangeLog b/gold/ChangeLog index c4c171d..bd842a6 100644 --- a/gold/ChangeLog +++ b/gold/ChangeLog @@ -1,3 +1,20 @@ +2017-11-08 H.J. Lu <hongjiu.lu@intel.com> + + 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. + 2017-11-08 James Clarke <jrtc27@jrtc27.com> PR gold/22266 diff --git a/gold/layout.cc b/gold/layout.cc index 15c5434..351c4b4 100644 --- a/gold/layout.cc +++ b/gold/layout.cc @@ -2252,7 +2252,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 @@ -2265,7 +2265,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 7ebcd6b..d1f71e0 100644 --- a/gold/symtab.cc +++ b/gold/symtab.cc @@ -1761,6 +1761,7 @@ template<int size, bool big_endian> Sized_symbol<size>* Symbol_table::define_special_symbol(const char** pname, const char** pversion, bool only_if_ref, + elfcpp::STV visibility, Sized_symbol<size>** poldsym, bool* resolve_oldsym, bool is_forced_local) { @@ -1799,8 +1800,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 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) @@ -1975,7 +1989,9 @@ Symbol_table::do_define_in_output_data( { #if defined(HAVE_TARGET_32_BIG) || defined(HAVE_TARGET_64_BIG) sym = this->define_special_symbol<size, true>(&name, &version, - only_if_ref, &oldsym, + only_if_ref, + visibility, + &oldsym, &resolve_oldsym, is_forced_local); #else @@ -1986,7 +2002,9 @@ Symbol_table::do_define_in_output_data( { #if defined(HAVE_TARGET_32_LITTLE) || defined(HAVE_TARGET_64_LITTLE) sym = this->define_special_symbol<size, false>(&name, &version, - only_if_ref, &oldsym, + only_if_ref, + visibility, + &oldsym, &resolve_oldsym, is_forced_local); #else @@ -2094,7 +2112,9 @@ Symbol_table::do_define_in_output_segment( { #if defined(HAVE_TARGET_32_BIG) || defined(HAVE_TARGET_64_BIG) sym = this->define_special_symbol<size, true>(&name, &version, - only_if_ref, &oldsym, + only_if_ref, + visibility, + &oldsym, &resolve_oldsym, is_forced_local); #else @@ -2105,7 +2125,9 @@ Symbol_table::do_define_in_output_segment( { #if defined(HAVE_TARGET_32_LITTLE) || defined(HAVE_TARGET_64_LITTLE) sym = this->define_special_symbol<size, false>(&name, &version, - only_if_ref, &oldsym, + only_if_ref, + visibility, + &oldsym, &resolve_oldsym, is_forced_local); #else @@ -2211,7 +2233,9 @@ Symbol_table::do_define_as_constant( { #if defined(HAVE_TARGET_32_BIG) || defined(HAVE_TARGET_64_BIG) sym = this->define_special_symbol<size, true>(&name, &version, - only_if_ref, &oldsym, + only_if_ref, + visibility, + &oldsym, &resolve_oldsym, is_forced_local); #else @@ -2222,7 +2246,9 @@ Symbol_table::do_define_as_constant( { #if defined(HAVE_TARGET_32_LITTLE) || defined(HAVE_TARGET_64_LITTLE) sym = this->define_special_symbol<size, false>(&name, &version, - only_if_ref, &oldsym, + only_if_ref, + visibility, + &oldsym, &resolve_oldsym, is_forced_local); #else @@ -2449,7 +2475,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<size, true>(&name, &version, - false, &oldsym, + false, + elfcpp::STV_DEFAULT, + &oldsym, &resolve_oldsym, false); #else @@ -2460,7 +2488,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<size, false>(&name, &version, - false, &oldsym, + false, + elfcpp::STV_DEFAULT, + &oldsym, &resolve_oldsym, false); #else diff --git a/gold/symtab.h b/gold/symtab.h index a67d5eb..edf1c17 100644 --- a/gold/symtab.h +++ b/gold/symtab.h @@ -1830,7 +1830,8 @@ class Symbol_table template<int size, bool big_endian> Sized_symbol<size>* define_special_symbol(const char** pname, const char** pversion, - bool only_if_ref, Sized_symbol<size>** poldsym, + bool only_if_ref, elfcpp::STV visibility, + Sized_symbol<size>** poldsym, bool* resolve_oldsym, bool is_forced_local); // Define a symbol in an Output_data, sized version. |