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.
This commit is contained in:
parent
cb1a122cce
commit
dc8d2d90da
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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.
|
||||
|
|
Loading…
Reference in New Issue