This is the mail archive of the
binutils@sourceware.org
mailing list for the binutils project.
[PATCH] gold: Ignore definition from a dynamic object for __start/__stop
- From: "H.J. Lu" <hjl dot tools at gmail dot com>
- To: binutils at sourceware dot org
- Date: Wed, 18 Oct 2017 06:20:21 -0700
- Subject: [PATCH] gold: Ignore definition from a dynamic object for __start/__stop
- Authentication-results: sourceware.org; auth=none
Since __start and __stop symbols must be defined in a regular object,
definition from a dynamic object should 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
and set must_be_in_reg to true for __start and __stop symbols.
* symtab.cc (Symbol_table::define_special_symbol): Add an
argument, must_be_in_reg. If the symbol must be defined in a
regular object, ignore definition from a dynamic object.
(Symbol_table::define_in_output_data): Add an argument,
must_be_in_reg and pass it to do_define_in_output_data.
(Symbol_table::do_define_in_output_data): Add an argument,
must_be_in_reg and pass it to define_special_symbol.
* symtab.h (Symbol_table::define_in_output_data): Add an
argument, must_be_in_reg, and default to false.
(Symbol_table::define_special_symbol): Likewise.
(Symbol_table::do_define_in_output_data): Likewise.
---
gold/layout.cc | 10 ++++++----
gold/symtab.cc | 28 ++++++++++++++++++++--------
gold/symtab.h | 9 ++++++---
3 files changed, 32 insertions(+), 15 deletions(-)
diff --git a/gold/layout.cc b/gold/layout.cc
index 5f25faea55..bdfceee3b2 100644
--- a/gold/layout.cc
+++ b/gold/layout.cc
@@ -2228,10 +2228,11 @@ 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
+ true, // only_if_ref
+ true); // must_be_in_reg
symtab->define_in_output_data(stop_name.c_str(),
NULL, // version
@@ -2241,10 +2242,11 @@ 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
+ true, // only_if_ref
+ true); // must_be_in_reg
}
}
}
diff --git a/gold/symtab.cc b/gold/symtab.cc
index 1555de6e5b..6a8eb6d9c3 100644
--- a/gold/symtab.cc
+++ b/gold/symtab.cc
@@ -1760,7 +1760,9 @@ Sized_symbol<size>*
Symbol_table::define_special_symbol(const char** pname, const char** pversion,
bool only_if_ref,
Sized_symbol<size>** poldsym,
- bool* resolve_oldsym, bool is_forced_local)
+ bool* resolve_oldsym,
+ bool is_forced_local,
+ bool must_be_in_reg)
{
*resolve_oldsym = false;
*poldsym = NULL;
@@ -1797,7 +1799,11 @@ 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 the symbol must be defined in a regular object, ignore
+ // definition from a dynamic object.
+ if (oldsym == NULL
+ || (!oldsym->is_undefined()
+ && (!must_be_in_reg || !oldsym->is_from_dynobj())))
return NULL;
*pname = oldsym->name();
@@ -1916,7 +1922,8 @@ Symbol_table::define_in_output_data(const char* name,
elfcpp::STV visibility,
unsigned char nonvis,
bool offset_is_from_end,
- bool only_if_ref)
+ bool only_if_ref,
+ bool must_be_in_reg)
{
if (parameters->target().get_size() == 32)
{
@@ -1925,7 +1932,8 @@ Symbol_table::define_in_output_data(const char* name,
value, symsize, type, binding,
visibility, nonvis,
offset_is_from_end,
- only_if_ref);
+ only_if_ref,
+ must_be_in_reg);
#else
gold_unreachable();
#endif
@@ -1937,7 +1945,8 @@ Symbol_table::define_in_output_data(const char* name,
value, symsize, type, binding,
visibility, nonvis,
offset_is_from_end,
- only_if_ref);
+ only_if_ref,
+ must_be_in_reg);
#else
gold_unreachable();
#endif
@@ -1962,7 +1971,8 @@ Symbol_table::do_define_in_output_data(
elfcpp::STV visibility,
unsigned char nonvis,
bool offset_is_from_end,
- bool only_if_ref)
+ bool only_if_ref,
+ bool must_be_in_reg)
{
Sized_symbol<size>* sym;
Sized_symbol<size>* oldsym;
@@ -1975,7 +1985,8 @@ Symbol_table::do_define_in_output_data(
sym = this->define_special_symbol<size, true>(&name, &version,
only_if_ref, &oldsym,
&resolve_oldsym,
- is_forced_local);
+ is_forced_local,
+ must_be_in_reg);
#else
gold_unreachable();
#endif
@@ -1986,7 +1997,8 @@ Symbol_table::do_define_in_output_data(
sym = this->define_special_symbol<size, false>(&name, &version,
only_if_ref, &oldsym,
&resolve_oldsym,
- is_forced_local);
+ is_forced_local,
+ must_be_in_reg);
#else
gold_unreachable();
#endif
diff --git a/gold/symtab.h b/gold/symtab.h
index a67d5eb90d..27c0f8972e 100644
--- a/gold/symtab.h
+++ b/gold/symtab.h
@@ -1507,7 +1507,8 @@ class Symbol_table
Output_data*, uint64_t value, uint64_t symsize,
elfcpp::STT type, elfcpp::STB binding,
elfcpp::STV visibility, unsigned char nonvis,
- bool offset_is_from_end, bool only_if_ref);
+ bool offset_is_from_end, bool only_if_ref,
+ bool must_be_in_reg = false);
// Define a special symbol based on an Output_segment. It is a
// multiple definition error if this symbol is already defined.
@@ -1831,7 +1832,8 @@ class Symbol_table
Sized_symbol<size>*
define_special_symbol(const char** pname, const char** pversion,
bool only_if_ref, Sized_symbol<size>** poldsym,
- bool* resolve_oldsym, bool is_forced_local);
+ bool* resolve_oldsym, bool is_forced_local,
+ bool must_be_in_reg = false);
// Define a symbol in an Output_data, sized version.
template<int size>
@@ -1842,7 +1844,8 @@ class Symbol_table
typename elfcpp::Elf_types<size>::Elf_WXword ssize,
elfcpp::STT type, elfcpp::STB binding,
elfcpp::STV visibility, unsigned char nonvis,
- bool offset_is_from_end, bool only_if_ref);
+ bool offset_is_from_end, bool only_if_ref,
+ bool must_be_in_reg = false);
// Define a symbol in an Output_segment, sized version.
template<int size>
--
2.13.6