* [PATCH v4] gold: Fix non-deterministic behaviour of Mips gold.
@ 2016-04-07 13:28 Vladimir Radosavljevic
2016-04-07 14:42 ` Cary Coutant
2016-05-19 22:09 ` Cary Coutant
0 siblings, 2 replies; 9+ messages in thread
From: Vladimir Radosavljevic @ 2016-04-07 13:28 UTC (permalink / raw)
To: binutils; +Cc: ccoutant, Petar Jovanovic
[-- Attachment #1: Type: text/plain, Size: 1863 bytes --]
Comments addressed.
Regards,
Vladimir
ChangeLog -
* mips.cc (Mips_got_entry::Mips_got_entry): Remove object argument
for global got symbols, and set addend to 0.
(Mips_got_entry::hash): Change hash algorithm.
(Mips_got_entry::equals): Refactor.
(Mips_got_entry::object): Return input object for local got symbols
from union d.
(Mips_got_entry::addend): Change return of the relocation addend.
(Mips_got_entry::addend_): Move from union d.
(Mips_got_entry::object_): Move into union d.
(class Mips_symbol_hash): New class.
(Mips_got_info::Global_got_entry_set): New type.
(Mips_got_info::global_got_symbols): Change return type to
Global_got_entry_set.
(Mips_got_info::global_got_symbols_): Change type to
Global_got_entry_set.
(Mips_symbol::hash): New method.
(Mips_output_data_la25_stub::symbols_): Change type to std::vector.
(Mips_output_data_mips_stubs::Mips_stubs_entry_set): New type.
(Mips_output_data_mips_stubs::symbols_): Change type to
Mips_stubs_entry_set.
(Mips_got_info::record_global_got_symbol): Don't pass object
argument when creating global got symbol.
(Mips_got_info::record_got_entry): Remove find before inserting
got entries.
(Mips_got_info::add_reloc_only_entries): Change type of iterator
to Global_got_entry_set.
(Mips_got_info::count_got_symbols): Likewise.
(Mips_output_data_la25_stub::create_la25_stub): Use push_back
for adding entries to symbols_.
(Mips_output_data_la25_stub::do_write): Change type of iterator
to std::vector.
(Mips_output_data_mips_stubs::set_lazy_stub_offsets): Change type
of iterator to Mips_stubs_entry_set.
(Mips_output_data_mips_stubs::set_needs_dynsym_value): Likewise.
(Mips_output_data_mips_stubs::do_write): Likewise.
[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #2: fix-non-deterministic-behaviour.patch --]
[-- Type: text/x-patch; name="fix-non-deterministic-behaviour.patch", Size: 11347 bytes --]
diff --git a/gold/mips.cc b/gold/mips.cc
index ffaad45..698d683 100644
--- a/gold/mips.cc
+++ b/gold/mips.cc
@@ -420,8 +420,8 @@ is_matching_lo16_reloc(unsigned int high_reloc, unsigned int lo16_reloc)
// (1) a SYMBOL + OFFSET address, where SYMBOL is local to an input object
// (object != NULL, symndx >= 0, tls_type != GOT_TLS_LDM)
// (2) a SYMBOL address, where SYMBOL is not local to an input object
-// (object != NULL, symndx == -1)
-// (3) a TLS LDM slot
+// (sym != NULL, symndx == -1)
+// (3) a TLS LDM slot (there's only one of these per GOT.)
// (object != NULL, symndx == 0, tls_type == GOT_TLS_LDM)
template<int size, bool big_endian>
@@ -433,13 +433,12 @@ class Mips_got_entry
Mips_got_entry(Mips_relobj<size, big_endian>* object, unsigned int symndx,
Mips_address addend, unsigned char tls_type,
unsigned int shndx, bool is_section_symbol)
- : object_(object), symndx_(symndx), tls_type_(tls_type),
+ : addend_(addend), symndx_(symndx), tls_type_(tls_type),
is_section_symbol_(is_section_symbol), shndx_(shndx)
- { this->d.addend = addend; }
+ { this->d.object = object; }
- Mips_got_entry(Mips_relobj<size, big_endian>* object, Mips_symbol<size>* sym,
- unsigned char tls_type)
- : object_(object), symndx_(-1U), tls_type_(tls_type),
+ Mips_got_entry(Mips_symbol<size>* sym, unsigned char tls_type)
+ : addend_(0), symndx_(-1U), tls_type_(tls_type),
is_section_symbol_(false), shndx_(-1U)
{ this->d.sym = sym; }
@@ -459,40 +458,38 @@ class Mips_got_entry
{
if (this->tls_type_ == GOT_TLS_LDM)
return this->symndx_ + (1 << 18);
- if (this->symndx_ != -1U)
- {
- uintptr_t object_id = reinterpret_cast<uintptr_t>(this->object());
- return this->symndx_ + object_id + this->d.addend;
- }
- else
- {
- uintptr_t sym_id = reinterpret_cast<uintptr_t>(this->d.sym);
- return this->symndx_ + sym_id;
- }
+
+ size_t name_hash_value = gold::string_hash<char>(
+ (this->symndx_ != -1U)
+ ? this->d.object->name().c_str()
+ : this->d.sym->name());
+ size_t addend = (sizeof(size_t) == 8
+ ? (this->addend_ & 0xffffffffffff) << 16
+ : (this->addend_ & 0xffff) << 16);
+ return name_hash_value ^ this->symndx_ ^ addend;
}
// Return whether this entry is equal to OTHER.
bool
equals(Mips_got_entry<size, big_endian>* other) const
{
- if (this->symndx_ != other->symndx_
- || this->tls_type_ != other->tls_type_)
- return false;
if (this->tls_type_ == GOT_TLS_LDM)
return true;
- if (this->symndx_ != -1U)
- return (this->object() == other->object()
- && this->d.addend == other->d.addend);
- else
- return this->d.sym == other->d.sym;
+
+ return ((this->tls_type_ == other->tls_type_)
+ && (this->symndx_ == other->symndx_)
+ && ((this->symndx_ != -1U)
+ ? (this->d.object == other->d.object)
+ : (this->d.sym == other->d.sym))
+ && (this->addend_ == other->addend_));
}
// Return input object that needs this GOT entry.
Mips_relobj<size, big_endian>*
object() const
{
- gold_assert(this->object_ != NULL);
- return this->object_;
+ gold_assert(this->symndx_ != -1U);
+ return this->d.object;
}
// Return local symbol index for local GOT entries.
@@ -506,10 +503,7 @@ class Mips_got_entry
// Return the relocation addend for local GOT entries.
Mips_address
addend() const
- {
- gold_assert(this->symndx_ != -1U);
- return this->d.addend;
- }
+ { return this->addend_; }
// Return global symbol for global GOT entries.
Mips_symbol<size>*
@@ -540,16 +534,16 @@ class Mips_got_entry
{ return this->is_section_symbol_; }
private:
- // The input object that needs the GOT entry.
- Mips_relobj<size, big_endian>* object_;
+ // The addend.
+ Mips_address addend_;
+
// The index of the symbol if we have a local symbol; -1 otherwise.
unsigned int symndx_;
union
{
- // If symndx != -1, the addend of the relocation that should be added to the
- // symbol value.
- Mips_address addend;
+ // The input object for local symbols that needs the GOT entry.
+ Mips_relobj<size, big_endian>* object;
// If symndx == -1, the global symbol corresponding to this GOT entry. The
// symbol's entry is in the local area if mips_sym->global_got_area is
// GGA_NONE, otherwise it is in the global area.
@@ -590,6 +584,17 @@ class Mips_got_entry_eq
{ return e1->equals(e2); }
};
+// Hash for Mips_symbol.
+
+template<int size>
+class Mips_symbol_hash
+{
+ public:
+ size_t
+ operator()(Mips_symbol<size>* sym) const
+ { return sym->hash(); }
+};
+
// Got_page_range. This class describes a range of addends: [MIN_ADDEND,
// MAX_ADDEND]. The instances form a non-overlapping list that is sorted by
// increasing MIN_ADDEND.
@@ -672,6 +677,10 @@ class Mips_got_info
typedef Unordered_set<Got_page_entry*,
Got_page_entry_hash, Got_page_entry_eq> Got_page_entry_set;
+ // Unordered set of global GOT entries.
+ typedef Unordered_set<Mips_symbol<size>*, Mips_symbol_hash<size> >
+ Global_got_entry_set;
+
public:
Mips_got_info()
: local_gotno_(0), page_gotno_(0), global_gotno_(0), reloc_only_gotno_(0),
@@ -851,7 +860,7 @@ class Mips_got_info
set_tls_ldm_offset(unsigned int tls_ldm_offset)
{ this->tls_ldm_offset_ = tls_ldm_offset; }
- Unordered_set<Mips_symbol<size>*>&
+ Global_got_entry_set&
global_got_symbols()
{ return this->global_got_symbols_; }
@@ -906,7 +915,7 @@ class Mips_got_info
// The offset of TLS LDM entry for this GOT.
unsigned int tls_ldm_offset_;
// All symbols that have global GOT entry.
- Unordered_set<Mips_symbol<size>*> global_got_symbols_;
+ Global_got_entry_set global_got_symbols_;
// A hash table holding GOT entries.
Got_entry_set got_entries_;
// A hash table of GOT page entries.
@@ -1284,6 +1293,13 @@ class Mips_symbol : public Sized_symbol<size>
set_applied_secondary_got_fixup()
{ this->applied_secondary_got_fixup_ = true; }
+ // Return the hash of this symbol.
+ size_t
+ hash() const
+ {
+ return gold::string_hash<char>(this->name());
+ }
+
private:
// Whether the symbol needs MIPS16 fn_stub. This is true if this symbol
// appears in any relocs other than a 16 bit call.
@@ -2302,7 +2318,7 @@ class Mips_output_data_la25_stub : public Output_section_data
do_write(Output_file*);
// Symbols that have LA25 stubs.
- Unordered_set<Mips_symbol<size>*> symbols_;
+ std::vector<Mips_symbol<size>*> symbols_;
};
// MIPS-specific relocation writer.
@@ -2577,6 +2593,10 @@ class Mips_output_data_mips_stubs : public Output_section_data
{
typedef typename elfcpp::Elf_types<size>::Elf_Addr Mips_address;
+ // Unordered set of .MIPS.stubs entries.
+ typedef Unordered_set<Mips_symbol<size>*, Mips_symbol_hash<size> >
+ Mips_stubs_entry_set;
+
public:
Mips_output_data_mips_stubs(Target_mips<size, big_endian>* target)
: Output_section_data(size == 32 ? 4 : 8), symbols_(), dynsym_count_(-1U),
@@ -2683,7 +2703,7 @@ class Mips_output_data_mips_stubs : public Output_section_data
do_write(Output_file*);
// .MIPS.stubs symbols
- Unordered_set<Mips_symbol<size>*> symbols_;
+ Mips_stubs_entry_set symbols_;
// Number of entries in dynamic symbol table.
unsigned int dynsym_count_;
// Whether the stub offsets are set.
@@ -5277,7 +5297,7 @@ Mips_got_info<size, big_endian>::record_global_got_symbol(
}
Mips_got_entry<size, big_endian>* entry =
- new Mips_got_entry<size, big_endian>(object, mips_sym, tls_type);
+ new Mips_got_entry<size, big_endian>(mips_sym, tls_type);
this->record_got_entry(entry, object);
}
@@ -5290,16 +5310,14 @@ Mips_got_info<size, big_endian>::record_got_entry(
Mips_got_entry<size, big_endian>* entry,
Mips_relobj<size, big_endian>* object)
{
- if (this->got_entries_.find(entry) == this->got_entries_.end())
- this->got_entries_.insert(entry);
+ this->got_entries_.insert(entry);
// Create the GOT entry for the OBJECT's GOT.
Mips_got_info<size, big_endian>* g = object->get_or_create_got_info();
Mips_got_entry<size, big_endian>* entry2 =
new Mips_got_entry<size, big_endian>(*entry);
- if (g->got_entries_.find(entry2) == g->got_entries_.end())
- g->got_entries_.insert(entry2);
+ g->got_entries_.insert(entry2);
}
// Record that OBJECT has a page relocation against symbol SYMNDX and
@@ -5573,7 +5591,7 @@ void
Mips_got_info<size, big_endian>::add_reloc_only_entries(
Mips_output_data_got<size, big_endian>* got)
{
- for (typename Unordered_set<Mips_symbol<size>*>::iterator
+ for (typename Global_got_entry_set::iterator
p = this->global_got_symbols_.begin();
p != this->global_got_symbols_.end();
++p)
@@ -5757,7 +5775,7 @@ template<int size, bool big_endian>
void
Mips_got_info<size, big_endian>::count_got_symbols(Symbol_table* symtab)
{
- for (typename Unordered_set<Mips_symbol<size>*>::iterator
+ for (typename Global_got_entry_set::iterator
p = this->global_got_symbols_.begin();
p != this->global_got_symbols_.end();
++p)
@@ -6635,7 +6653,7 @@ Mips_output_data_la25_stub<size, big_endian>::create_la25_stub(
if (!gsym->has_la25_stub())
{
gsym->set_la25_stub_offset(this->symbols_.size() * 16);
- this->symbols_.insert(gsym);
+ this->symbols_.push_back(gsym);
this->create_stub_symbol(gsym, symtab, target, 16);
}
}
@@ -6679,7 +6697,7 @@ Mips_output_data_la25_stub<size, big_endian>::do_write(Output_file* of)
convert_to_section_size_type(this->data_size());
unsigned char* const oview = of->get_output_view(offset, oview_size);
- for (typename Unordered_set<Mips_symbol<size>*>::iterator
+ for (typename std::vector<Mips_symbol<size>*>::iterator
p = this->symbols_.begin();
p != this->symbols_.end();
++p)
@@ -7478,7 +7496,7 @@ Mips_output_data_mips_stubs<size, big_endian>::set_lazy_stub_offsets()
unsigned int stub_size = this->stub_size();
unsigned int offset = 0;
- for (typename Unordered_set<Mips_symbol<size>*>::const_iterator
+ for (typename Mips_stubs_entry_set::const_iterator
p = this->symbols_.begin();
p != this->symbols_.end();
++p, offset += stub_size)
@@ -7493,7 +7511,7 @@ template<int size, bool big_endian>
void
Mips_output_data_mips_stubs<size, big_endian>::set_needs_dynsym_value()
{
- for (typename Unordered_set<Mips_symbol<size>*>::const_iterator
+ for (typename Mips_stubs_entry_set::const_iterator
p = this->symbols_.begin(); p != this->symbols_.end(); ++p)
{
Mips_symbol<size>* sym = *p;
@@ -7517,7 +7535,7 @@ Mips_output_data_mips_stubs<size, big_endian>::do_write(Output_file* of)
bool big_stub = this->dynsym_count_ > 0x10000;
unsigned char* pov = oview;
- for (typename Unordered_set<Mips_symbol<size>*>::const_iterator
+ for (typename Mips_stubs_entry_set::const_iterator
p = this->symbols_.begin(); p != this->symbols_.end(); ++p)
{
Mips_symbol<size>* sym = *p;
^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [PATCH v4] gold: Fix non-deterministic behaviour of Mips gold.
2016-04-07 13:28 [PATCH v4] gold: Fix non-deterministic behaviour of Mips gold Vladimir Radosavljevic
@ 2016-04-07 14:42 ` Cary Coutant
2016-04-07 14:52 ` Vladimir Radosavljevic
2016-05-19 22:09 ` Cary Coutant
1 sibling, 1 reply; 9+ messages in thread
From: Cary Coutant @ 2016-04-07 14:42 UTC (permalink / raw)
To: Vladimir Radosavljevic; +Cc: binutils, Petar Jovanovic
+ size_t addend = (sizeof(size_t) == 8
+ ? (this->addend_ & 0xffffffffffff) << 16
+ : (this->addend_ & 0xffff) << 16);
+ return name_hash_value ^ this->symndx_ ^ addend;
Mips_got_entry::addend_ is of type Mips_address, which is
Elf_types<size>::Elf_addr, So if you're building on a 64-bit host for
a 32-bit target, you'll have a 32-bit this->addend_, but a 64-bit
size_t. It's not clear to me why you want to mask the addend in either
case, though, and you're not taking advantage of a larger size_t by
shifting it further left. How about just this:
size_t addend = this->addend_;
return name_hash_value ^ this->symndx_ ^ (addend << 16);
If that's OK with you, I'll commit it with that change.
-cary
^ permalink raw reply [flat|nested] 9+ messages in thread
* RE: [PATCH v4] gold: Fix non-deterministic behaviour of Mips gold.
2016-04-07 14:42 ` Cary Coutant
@ 2016-04-07 14:52 ` Vladimir Radosavljevic
2016-05-04 13:23 ` Vladimir Radosavljevic
0 siblings, 1 reply; 9+ messages in thread
From: Vladimir Radosavljevic @ 2016-04-07 14:52 UTC (permalink / raw)
To: Cary Coutant; +Cc: binutils, Petar Jovanovic
> If that's OK with you, I'll commit it with that change.
Yes, I am ok with this.
Regards,
Vladimir
^ permalink raw reply [flat|nested] 9+ messages in thread
* RE: [PATCH v4] gold: Fix non-deterministic behaviour of Mips gold.
2016-04-07 14:52 ` Vladimir Radosavljevic
@ 2016-05-04 13:23 ` Vladimir Radosavljevic
2016-05-09 4:53 ` Cary Coutant
0 siblings, 1 reply; 9+ messages in thread
From: Vladimir Radosavljevic @ 2016-05-04 13:23 UTC (permalink / raw)
To: Cary Coutant; +Cc: binutils, Petar Jovanovic
Hi Cary,
Is there anything else I need to do for this patch?
Regards,
Vladimir
^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [PATCH v4] gold: Fix non-deterministic behaviour of Mips gold.
2016-05-04 13:23 ` Vladimir Radosavljevic
@ 2016-05-09 4:53 ` Cary Coutant
0 siblings, 0 replies; 9+ messages in thread
From: Cary Coutant @ 2016-05-09 4:53 UTC (permalink / raw)
To: Vladimir Radosavljevic; +Cc: binutils, Petar Jovanovic
> Is there anything else I need to do for this patch?
No, sorry, I meant to commit it, but forgot. I'm out of town at the
moment, but I'll get it in when I return on Wednesday.
-cary
^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [PATCH v4] gold: Fix non-deterministic behaviour of Mips gold.
2016-04-07 13:28 [PATCH v4] gold: Fix non-deterministic behaviour of Mips gold Vladimir Radosavljevic
2016-04-07 14:42 ` Cary Coutant
@ 2016-05-19 22:09 ` Cary Coutant
2016-05-25 7:51 ` Artemiy Volkov
1 sibling, 1 reply; 9+ messages in thread
From: Cary Coutant @ 2016-05-19 22:09 UTC (permalink / raw)
To: Vladimir Radosavljevic; +Cc: binutils, Petar Jovanovic
[-- Attachment #1: Type: text/plain, Size: 1941 bytes --]
> * mips.cc (Mips_got_entry::Mips_got_entry): Remove object argument
> for global got symbols, and set addend to 0.
> (Mips_got_entry::hash): Change hash algorithm.
> (Mips_got_entry::equals): Refactor.
> (Mips_got_entry::object): Return input object for local got symbols
> from union d.
> (Mips_got_entry::addend): Change return of the relocation addend.
> (Mips_got_entry::addend_): Move from union d.
> (Mips_got_entry::object_): Move into union d.
> (class Mips_symbol_hash): New class.
> (Mips_got_info::Global_got_entry_set): New type.
> (Mips_got_info::global_got_symbols): Change return type to
> Global_got_entry_set.
> (Mips_got_info::global_got_symbols_): Change type to
> Global_got_entry_set.
> (Mips_symbol::hash): New method.
> (Mips_output_data_la25_stub::symbols_): Change type to std::vector.
> (Mips_output_data_mips_stubs::Mips_stubs_entry_set): New type.
> (Mips_output_data_mips_stubs::symbols_): Change type to
> Mips_stubs_entry_set.
> (Mips_got_info::record_global_got_symbol): Don't pass object
> argument when creating global got symbol.
> (Mips_got_info::record_got_entry): Remove find before inserting
> got entries.
> (Mips_got_info::add_reloc_only_entries): Change type of iterator
> to Global_got_entry_set.
> (Mips_got_info::count_got_symbols): Likewise.
> (Mips_output_data_la25_stub::create_la25_stub): Use push_back
> for adding entries to symbols_.
> (Mips_output_data_la25_stub::do_write): Change type of iterator
> to std::vector.
> (Mips_output_data_mips_stubs::set_lazy_stub_offsets): Change type
> of iterator to Mips_stubs_entry_set.
> (Mips_output_data_mips_stubs::set_needs_dynsym_value): Likewise.
> (Mips_output_data_mips_stubs::do_write): Likewise.
Committed with the suggested change. Revised patch attached.
Thanks, and sorry for the delay!
-cary
[-- Attachment #2: fix-non-deterministic-behaviour-4.patch --]
[-- Type: application/octet-stream, Size: 13087 bytes --]
Fix non-deterministic behavior when generating MIPS GOT.
* mips.cc (Mips_got_entry::Mips_got_entry): Remove object argument
for global got symbols, and set addend to 0.
(Mips_got_entry::hash): Change hash algorithm.
(Mips_got_entry::equals): Refactor.
(Mips_got_entry::object): Return input object for local got symbols
from union d.
(Mips_got_entry::addend): Change return of the relocation addend.
(Mips_got_entry::addend_): Move from union d.
(Mips_got_entry::object_): Move into union d.
(class Mips_symbol_hash): New class.
(Mips_got_info::Global_got_entry_set): New type.
(Mips_got_info::global_got_symbols): Change return type to
Global_got_entry_set.
(Mips_got_info::global_got_symbols_): Change type to
Global_got_entry_set.
(Mips_symbol::hash): New method.
(Mips_output_data_la25_stub::symbols_): Change type to std::vector.
(Mips_output_data_mips_stubs::Mips_stubs_entry_set): New type.
(Mips_output_data_mips_stubs::symbols_): Change type to
Mips_stubs_entry_set.
(Mips_got_info::record_global_got_symbol): Don't pass object
argument when creating global got symbol.
(Mips_got_info::record_got_entry): Remove find before inserting
got entries.
(Mips_got_info::add_reloc_only_entries): Change type of iterator
to Global_got_entry_set.
(Mips_got_info::count_got_symbols): Likewise.
(Mips_output_data_la25_stub::create_la25_stub): Use push_back
for adding entries to symbols_.
(Mips_output_data_la25_stub::do_write): Change type of iterator
to std::vector.
(Mips_output_data_mips_stubs::set_lazy_stub_offsets): Change type
of iterator to Mips_stubs_entry_set.
(Mips_output_data_mips_stubs::set_needs_dynsym_value): Likewise.
(Mips_output_data_mips_stubs::do_write): Likewise.
diff --git a/gold/mips.cc b/gold/mips.cc
index ffaad45..e622e29 100644
--- a/gold/mips.cc
+++ b/gold/mips.cc
@@ -420,8 +420,8 @@ is_matching_lo16_reloc(unsigned int high_reloc, unsigned int lo16_reloc)
// (1) a SYMBOL + OFFSET address, where SYMBOL is local to an input object
// (object != NULL, symndx >= 0, tls_type != GOT_TLS_LDM)
// (2) a SYMBOL address, where SYMBOL is not local to an input object
-// (object != NULL, symndx == -1)
-// (3) a TLS LDM slot
+// (sym != NULL, symndx == -1)
+// (3) a TLS LDM slot (there's only one of these per GOT.)
// (object != NULL, symndx == 0, tls_type == GOT_TLS_LDM)
template<int size, bool big_endian>
@@ -433,13 +433,12 @@ class Mips_got_entry
Mips_got_entry(Mips_relobj<size, big_endian>* object, unsigned int symndx,
Mips_address addend, unsigned char tls_type,
unsigned int shndx, bool is_section_symbol)
- : object_(object), symndx_(symndx), tls_type_(tls_type),
+ : addend_(addend), symndx_(symndx), tls_type_(tls_type),
is_section_symbol_(is_section_symbol), shndx_(shndx)
- { this->d.addend = addend; }
+ { this->d.object = object; }
- Mips_got_entry(Mips_relobj<size, big_endian>* object, Mips_symbol<size>* sym,
- unsigned char tls_type)
- : object_(object), symndx_(-1U), tls_type_(tls_type),
+ Mips_got_entry(Mips_symbol<size>* sym, unsigned char tls_type)
+ : addend_(0), symndx_(-1U), tls_type_(tls_type),
is_section_symbol_(false), shndx_(-1U)
{ this->d.sym = sym; }
@@ -459,40 +458,36 @@ class Mips_got_entry
{
if (this->tls_type_ == GOT_TLS_LDM)
return this->symndx_ + (1 << 18);
- if (this->symndx_ != -1U)
- {
- uintptr_t object_id = reinterpret_cast<uintptr_t>(this->object());
- return this->symndx_ + object_id + this->d.addend;
- }
- else
- {
- uintptr_t sym_id = reinterpret_cast<uintptr_t>(this->d.sym);
- return this->symndx_ + sym_id;
- }
+
+ size_t name_hash_value = gold::string_hash<char>(
+ (this->symndx_ != -1U)
+ ? this->d.object->name().c_str()
+ : this->d.sym->name());
+ size_t addend = this->addend_;
+ return name_hash_value ^ this->symndx_ ^ addend;
}
// Return whether this entry is equal to OTHER.
bool
equals(Mips_got_entry<size, big_endian>* other) const
{
- if (this->symndx_ != other->symndx_
- || this->tls_type_ != other->tls_type_)
- return false;
if (this->tls_type_ == GOT_TLS_LDM)
return true;
- if (this->symndx_ != -1U)
- return (this->object() == other->object()
- && this->d.addend == other->d.addend);
- else
- return this->d.sym == other->d.sym;
+
+ return ((this->tls_type_ == other->tls_type_)
+ && (this->symndx_ == other->symndx_)
+ && ((this->symndx_ != -1U)
+ ? (this->d.object == other->d.object)
+ : (this->d.sym == other->d.sym))
+ && (this->addend_ == other->addend_));
}
// Return input object that needs this GOT entry.
Mips_relobj<size, big_endian>*
object() const
{
- gold_assert(this->object_ != NULL);
- return this->object_;
+ gold_assert(this->symndx_ != -1U);
+ return this->d.object;
}
// Return local symbol index for local GOT entries.
@@ -506,10 +501,7 @@ class Mips_got_entry
// Return the relocation addend for local GOT entries.
Mips_address
addend() const
- {
- gold_assert(this->symndx_ != -1U);
- return this->d.addend;
- }
+ { return this->addend_; }
// Return global symbol for global GOT entries.
Mips_symbol<size>*
@@ -540,16 +532,16 @@ class Mips_got_entry
{ return this->is_section_symbol_; }
private:
- // The input object that needs the GOT entry.
- Mips_relobj<size, big_endian>* object_;
+ // The addend.
+ Mips_address addend_;
+
// The index of the symbol if we have a local symbol; -1 otherwise.
unsigned int symndx_;
union
{
- // If symndx != -1, the addend of the relocation that should be added to the
- // symbol value.
- Mips_address addend;
+ // The input object for local symbols that needs the GOT entry.
+ Mips_relobj<size, big_endian>* object;
// If symndx == -1, the global symbol corresponding to this GOT entry. The
// symbol's entry is in the local area if mips_sym->global_got_area is
// GGA_NONE, otherwise it is in the global area.
@@ -590,6 +582,17 @@ class Mips_got_entry_eq
{ return e1->equals(e2); }
};
+// Hash for Mips_symbol.
+
+template<int size>
+class Mips_symbol_hash
+{
+ public:
+ size_t
+ operator()(Mips_symbol<size>* sym) const
+ { return sym->hash(); }
+};
+
// Got_page_range. This class describes a range of addends: [MIN_ADDEND,
// MAX_ADDEND]. The instances form a non-overlapping list that is sorted by
// increasing MIN_ADDEND.
@@ -672,6 +675,10 @@ class Mips_got_info
typedef Unordered_set<Got_page_entry*,
Got_page_entry_hash, Got_page_entry_eq> Got_page_entry_set;
+ // Unordered set of global GOT entries.
+ typedef Unordered_set<Mips_symbol<size>*, Mips_symbol_hash<size> >
+ Global_got_entry_set;
+
public:
Mips_got_info()
: local_gotno_(0), page_gotno_(0), global_gotno_(0), reloc_only_gotno_(0),
@@ -851,7 +858,7 @@ class Mips_got_info
set_tls_ldm_offset(unsigned int tls_ldm_offset)
{ this->tls_ldm_offset_ = tls_ldm_offset; }
- Unordered_set<Mips_symbol<size>*>&
+ Global_got_entry_set&
global_got_symbols()
{ return this->global_got_symbols_; }
@@ -906,7 +913,7 @@ class Mips_got_info
// The offset of TLS LDM entry for this GOT.
unsigned int tls_ldm_offset_;
// All symbols that have global GOT entry.
- Unordered_set<Mips_symbol<size>*> global_got_symbols_;
+ Global_got_entry_set global_got_symbols_;
// A hash table holding GOT entries.
Got_entry_set got_entries_;
// A hash table of GOT page entries.
@@ -1284,6 +1291,13 @@ class Mips_symbol : public Sized_symbol<size>
set_applied_secondary_got_fixup()
{ this->applied_secondary_got_fixup_ = true; }
+ // Return the hash of this symbol.
+ size_t
+ hash() const
+ {
+ return gold::string_hash<char>(this->name());
+ }
+
private:
// Whether the symbol needs MIPS16 fn_stub. This is true if this symbol
// appears in any relocs other than a 16 bit call.
@@ -2302,7 +2316,7 @@ class Mips_output_data_la25_stub : public Output_section_data
do_write(Output_file*);
// Symbols that have LA25 stubs.
- Unordered_set<Mips_symbol<size>*> symbols_;
+ std::vector<Mips_symbol<size>*> symbols_;
};
// MIPS-specific relocation writer.
@@ -2577,6 +2591,10 @@ class Mips_output_data_mips_stubs : public Output_section_data
{
typedef typename elfcpp::Elf_types<size>::Elf_Addr Mips_address;
+ // Unordered set of .MIPS.stubs entries.
+ typedef Unordered_set<Mips_symbol<size>*, Mips_symbol_hash<size> >
+ Mips_stubs_entry_set;
+
public:
Mips_output_data_mips_stubs(Target_mips<size, big_endian>* target)
: Output_section_data(size == 32 ? 4 : 8), symbols_(), dynsym_count_(-1U),
@@ -2683,7 +2701,7 @@ class Mips_output_data_mips_stubs : public Output_section_data
do_write(Output_file*);
// .MIPS.stubs symbols
- Unordered_set<Mips_symbol<size>*> symbols_;
+ Mips_stubs_entry_set symbols_;
// Number of entries in dynamic symbol table.
unsigned int dynsym_count_;
// Whether the stub offsets are set.
@@ -5277,7 +5295,7 @@ Mips_got_info<size, big_endian>::record_global_got_symbol(
}
Mips_got_entry<size, big_endian>* entry =
- new Mips_got_entry<size, big_endian>(object, mips_sym, tls_type);
+ new Mips_got_entry<size, big_endian>(mips_sym, tls_type);
this->record_got_entry(entry, object);
}
@@ -5290,16 +5308,14 @@ Mips_got_info<size, big_endian>::record_got_entry(
Mips_got_entry<size, big_endian>* entry,
Mips_relobj<size, big_endian>* object)
{
- if (this->got_entries_.find(entry) == this->got_entries_.end())
- this->got_entries_.insert(entry);
+ this->got_entries_.insert(entry);
// Create the GOT entry for the OBJECT's GOT.
Mips_got_info<size, big_endian>* g = object->get_or_create_got_info();
Mips_got_entry<size, big_endian>* entry2 =
new Mips_got_entry<size, big_endian>(*entry);
- if (g->got_entries_.find(entry2) == g->got_entries_.end())
- g->got_entries_.insert(entry2);
+ g->got_entries_.insert(entry2);
}
// Record that OBJECT has a page relocation against symbol SYMNDX and
@@ -5573,7 +5589,7 @@ void
Mips_got_info<size, big_endian>::add_reloc_only_entries(
Mips_output_data_got<size, big_endian>* got)
{
- for (typename Unordered_set<Mips_symbol<size>*>::iterator
+ for (typename Global_got_entry_set::iterator
p = this->global_got_symbols_.begin();
p != this->global_got_symbols_.end();
++p)
@@ -5757,7 +5773,7 @@ template<int size, bool big_endian>
void
Mips_got_info<size, big_endian>::count_got_symbols(Symbol_table* symtab)
{
- for (typename Unordered_set<Mips_symbol<size>*>::iterator
+ for (typename Global_got_entry_set::iterator
p = this->global_got_symbols_.begin();
p != this->global_got_symbols_.end();
++p)
@@ -6635,7 +6651,7 @@ Mips_output_data_la25_stub<size, big_endian>::create_la25_stub(
if (!gsym->has_la25_stub())
{
gsym->set_la25_stub_offset(this->symbols_.size() * 16);
- this->symbols_.insert(gsym);
+ this->symbols_.push_back(gsym);
this->create_stub_symbol(gsym, symtab, target, 16);
}
}
@@ -6679,7 +6695,7 @@ Mips_output_data_la25_stub<size, big_endian>::do_write(Output_file* of)
convert_to_section_size_type(this->data_size());
unsigned char* const oview = of->get_output_view(offset, oview_size);
- for (typename Unordered_set<Mips_symbol<size>*>::iterator
+ for (typename std::vector<Mips_symbol<size>*>::iterator
p = this->symbols_.begin();
p != this->symbols_.end();
++p)
@@ -7478,7 +7494,7 @@ Mips_output_data_mips_stubs<size, big_endian>::set_lazy_stub_offsets()
unsigned int stub_size = this->stub_size();
unsigned int offset = 0;
- for (typename Unordered_set<Mips_symbol<size>*>::const_iterator
+ for (typename Mips_stubs_entry_set::const_iterator
p = this->symbols_.begin();
p != this->symbols_.end();
++p, offset += stub_size)
@@ -7493,7 +7509,7 @@ template<int size, bool big_endian>
void
Mips_output_data_mips_stubs<size, big_endian>::set_needs_dynsym_value()
{
- for (typename Unordered_set<Mips_symbol<size>*>::const_iterator
+ for (typename Mips_stubs_entry_set::const_iterator
p = this->symbols_.begin(); p != this->symbols_.end(); ++p)
{
Mips_symbol<size>* sym = *p;
@@ -7517,7 +7533,7 @@ Mips_output_data_mips_stubs<size, big_endian>::do_write(Output_file* of)
bool big_stub = this->dynsym_count_ > 0x10000;
unsigned char* pov = oview;
- for (typename Unordered_set<Mips_symbol<size>*>::const_iterator
+ for (typename Mips_stubs_entry_set::const_iterator
p = this->symbols_.begin(); p != this->symbols_.end(); ++p)
{
Mips_symbol<size>* sym = *p;
^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [PATCH v4] gold: Fix non-deterministic behaviour of Mips gold.
2016-05-19 22:09 ` Cary Coutant
@ 2016-05-25 7:51 ` Artemiy Volkov
2016-05-25 13:49 ` Markus Trippelsdorf
0 siblings, 1 reply; 9+ messages in thread
From: Artemiy Volkov @ 2016-05-25 7:51 UTC (permalink / raw)
To: Cary Coutant; +Cc: Vladimir Radosavljevic, binutils, Petar Jovanovic
[-- Attachment #1: Type: text/plain, Size: 2268 bytes --]
On Fri, May 20, 2016 at 1:09 AM, Cary Coutant <ccoutant@gmail.com> wrote:
>> * mips.cc (Mips_got_entry::Mips_got_entry): Remove object argument
>> for global got symbols, and set addend to 0.
>> (Mips_got_entry::hash): Change hash algorithm.
>> (Mips_got_entry::equals): Refactor.
>> (Mips_got_entry::object): Return input object for local got symbols
>> from union d.
>> (Mips_got_entry::addend): Change return of the relocation addend.
>> (Mips_got_entry::addend_): Move from union d.
>> (Mips_got_entry::object_): Move into union d.
>> (class Mips_symbol_hash): New class.
>> (Mips_got_info::Global_got_entry_set): New type.
>> (Mips_got_info::global_got_symbols): Change return type to
>> Global_got_entry_set.
>> (Mips_got_info::global_got_symbols_): Change type to
>> Global_got_entry_set.
>> (Mips_symbol::hash): New method.
>> (Mips_output_data_la25_stub::symbols_): Change type to std::vector.
>> (Mips_output_data_mips_stubs::Mips_stubs_entry_set): New type.
>> (Mips_output_data_mips_stubs::symbols_): Change type to
>> Mips_stubs_entry_set.
>> (Mips_got_info::record_global_got_symbol): Don't pass object
>> argument when creating global got symbol.
>> (Mips_got_info::record_got_entry): Remove find before inserting
>> got entries.
>> (Mips_got_info::add_reloc_only_entries): Change type of iterator
>> to Global_got_entry_set.
>> (Mips_got_info::count_got_symbols): Likewise.
>> (Mips_output_data_la25_stub::create_la25_stub): Use push_back
>> for adding entries to symbols_.
>> (Mips_output_data_la25_stub::do_write): Change type of iterator
>> to std::vector.
>> (Mips_output_data_mips_stubs::set_lazy_stub_offsets): Change type
>> of iterator to Mips_stubs_entry_set.
>> (Mips_output_data_mips_stubs::set_needs_dynsym_value): Likewise.
>> (Mips_output_data_mips_stubs::do_write): Likewise.
>
> Committed with the suggested change. Revised patch attached.
>
> Thanks, and sorry for the delay!
>
> -cary
Hi,
this patch breaks the gold build for me since not all callers of
Mips_got_info::global_got_symbols() were adjusted to use the new
return type.
I have attached the easiest possible fix.
Thanks,
Artemiy
[-- Attachment #2: gold-mips-fix-global-got-symbols-callers.patch --]
[-- Type: text/x-patch, Size: 1064 bytes --]
diff --git a/gold/mips.cc b/gold/mips.cc
index b8c74d0..60c881e 100644
--- a/gold/mips.cc
+++ b/gold/mips.cc
@@ -6142,7 +6142,8 @@ Mips_output_data_got<size, big_endian>::do_write(Output_file* of)
this->got_view_ = oview;
// Write lazy stub addresses.
- for (typename Unordered_set<Mips_symbol<size>*>::iterator
+ for (typename Unordered_set<Mips_symbol<size>*,
+ Mips_symbol_hash<size> >::iterator
p = this->master_got_info_->global_got_symbols().begin();
p != this->master_got_info_->global_got_symbols().end();
++p)
@@ -6159,7 +6160,8 @@ Mips_output_data_got<size, big_endian>::do_write(Output_file* of)
}
// Add +1 to GGA_NONE nonzero MIPS16 and microMIPS entries.
- for (typename Unordered_set<Mips_symbol<size>*>::iterator
+ for (typename Unordered_set<Mips_symbol<size>*,
+ Mips_symbol_hash<size> >::iterator
p = this->master_got_info_->global_got_symbols().begin();
p != this->master_got_info_->global_got_symbols().end();
++p)
^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [PATCH v4] gold: Fix non-deterministic behaviour of Mips gold.
2016-05-25 7:51 ` Artemiy Volkov
@ 2016-05-25 13:49 ` Markus Trippelsdorf
2016-06-09 18:43 ` Cary Coutant
0 siblings, 1 reply; 9+ messages in thread
From: Markus Trippelsdorf @ 2016-05-25 13:49 UTC (permalink / raw)
To: Artemiy Volkov
Cc: Cary Coutant, Vladimir Radosavljevic, binutils, Petar Jovanovic
On 2016.05.25 at 10:50 +0300, Artemiy Volkov wrote:
> On Fri, May 20, 2016 at 1:09 AM, Cary Coutant <ccoutant@gmail.com> wrote:
> >> * mips.cc (Mips_got_entry::Mips_got_entry): Remove object argument
> > Committed with the suggested change. Revised patch attached.
> > -cary
>
> this patch breaks the gold build for me since not all callers of
> Mips_got_info::global_got_symbols() were adjusted to use the new
> return type.
>
> I have attached the easiest possible fix.
I ran into the same issue today.
Please just commit your fix, because I think the patch is obvious.
--
Markus
^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [PATCH v4] gold: Fix non-deterministic behaviour of Mips gold.
2016-05-25 13:49 ` Markus Trippelsdorf
@ 2016-06-09 18:43 ` Cary Coutant
0 siblings, 0 replies; 9+ messages in thread
From: Cary Coutant @ 2016-06-09 18:43 UTC (permalink / raw)
To: Markus Trippelsdorf
Cc: Artemiy Volkov, Vladimir Radosavljevic, binutils, Petar Jovanovic
>> this patch breaks the gold build for me since not all callers of
>> Mips_got_info::global_got_symbols() were adjusted to use the new
>> return type.
>>
>> I have attached the easiest possible fix.
>
> I ran into the same issue today.
> Please just commit your fix, because I think the patch is obvious.
I've committed the patch, but I used a typedef to improve the formatting.
Thanks, Artemiy!
-cary
2016-06-09 Artemiy Volkov <artemiyv@acm.org>
gold/
* mips.cc (Mips_output_data_got::do_write): Add missing template
args via typedef.
diff --git a/gold/mips.cc b/gold/mips.cc
index b8c74d0..e8a639b 100644
--- a/gold/mips.cc
+++ b/gold/mips.cc
@@ -6130,6 +6130,9 @@ template<int size, bool big_endian>
void
Mips_output_data_got<size, big_endian>::do_write(Output_file* of)
{
+ typedef Unordered_set<Mips_symbol<size>*, Mips_symbol_hash<size> >
+ Mips_stubs_entry_set;
+
// Call parent to write out GOT.
Output_data_got<size, big_endian>::do_write(of);
@@ -6142,7 +6145,7 @@ Mips_output_data_got<size,
big_endian>::do_write(Output_file* of)
this->got_view_ = oview;
// Write lazy stub addresses.
- for (typename Unordered_set<Mips_symbol<size>*>::iterator
+ for (typename Mips_stubs_entry_set::iterator
p = this->master_got_info_->global_got_symbols().begin();
p != this->master_got_info_->global_got_symbols().end();
++p)
@@ -6159,7 +6162,7 @@ Mips_output_data_got<size,
big_endian>::do_write(Output_file* of)
}
// Add +1 to GGA_NONE nonzero MIPS16 and microMIPS entries.
- for (typename Unordered_set<Mips_symbol<size>*>::iterator
+ for (typename Mips_stubs_entry_set::iterator
p = this->master_got_info_->global_got_symbols().begin();
p != this->master_got_info_->global_got_symbols().end();
++p)
^ permalink raw reply [flat|nested] 9+ messages in thread
end of thread, other threads:[~2016-06-09 18:43 UTC | newest]
Thread overview: 9+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2016-04-07 13:28 [PATCH v4] gold: Fix non-deterministic behaviour of Mips gold Vladimir Radosavljevic
2016-04-07 14:42 ` Cary Coutant
2016-04-07 14:52 ` Vladimir Radosavljevic
2016-05-04 13:23 ` Vladimir Radosavljevic
2016-05-09 4:53 ` Cary Coutant
2016-05-19 22:09 ` Cary Coutant
2016-05-25 7:51 ` Artemiy Volkov
2016-05-25 13:49 ` Markus Trippelsdorf
2016-06-09 18:43 ` Cary Coutant
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).