Index: incremental.h =================================================================== RCS file: /cvs/src/src/gold/incremental.h,v retrieving revision 1.32 diff -u -p -r1.32 incremental.h --- incremental.h 24 Apr 2012 22:05:28 -0000 1.32 +++ incremental.h 12 Sep 2012 18:23:10 -0000 @@ -1962,6 +1962,10 @@ class Sized_relobj_incr : public Sized_r do_local_plt_offset(unsigned int) const { gold_unreachable(); } + bool + do_local_is_tls(unsigned int) const + { gold_unreachable(); } + // Return the number of local symbols. unsigned int do_local_symbol_count() const Index: object.h =================================================================== RCS file: /cvs/src/src/gold/object.h,v retrieving revision 1.119 diff -u -p -r1.119 object.h --- object.h 5 Sep 2012 00:34:20 -0000 1.119 +++ object.h 12 Sep 2012 18:23:10 -0000 @@ -1079,6 +1079,11 @@ class Relobj : public Object unsigned int got_offset) { this->do_set_local_got_offset(symndx, got_type, got_offset); } + // Return whether the local symbol SYMNDX is a TLS symbol. + bool + local_is_tls(unsigned int symndx) const + { return this->do_local_is_tls(symndx); } + // The number of local symbols in the input symbol table. virtual unsigned int local_symbol_count() const @@ -1259,6 +1264,10 @@ class Relobj : public Object do_set_local_got_offset(unsigned int symndx, unsigned int got_type, unsigned int got_offset) = 0; + // Return whether local symbol SYMNDX is a TLS symbol. + virtual bool + do_local_is_tls(unsigned int symndx) const = 0; + // Return the number of local symbols--implemented by child class. virtual unsigned int do_local_symbol_count() const = 0; @@ -2166,6 +2175,11 @@ class Sized_relobj_file : public Sized_r unsigned int do_local_plt_offset(unsigned int symndx) const; + // Return whether local symbol SYMNDX is a TLS symbol. + bool + do_local_is_tls(unsigned int symndx) const + { return this->local_symbol(symndx)->is_tls_symbol(); } + // Return the number of local symbols. unsigned int do_local_symbol_count() const Index: output.cc =================================================================== RCS file: /cvs/src/src/gold/output.cc,v retrieving revision 1.173 diff -u -p -r1.173 output.cc --- output.cc 10 Sep 2012 23:10:41 -0000 1.173 +++ output.cc 12 Sep 2012 18:23:10 -0000 @@ -1367,9 +1367,9 @@ Output_data_group::do_ // Write out the entry. -template +template void -Output_data_got::Got_entry::write( +Output_data_got::Got_entry::write( unsigned int got_indx, unsigned char* pov) const { @@ -1388,13 +1388,36 @@ Output_data_got::Got_e + gsym->plt_offset()); else { - Sized_symbol* sgsym; - // This cast is a bit ugly. We don't want to put a - // virtual method in Symbol, because we want Symbol to be - // as small as possible. - sgsym = static_cast*>(gsym); - val = sgsym->value(); - if (this->use_plt_or_tls_offset_ && gsym->type() == elfcpp::STT_TLS) + switch (parameters->size_and_endianness()) + { +#if defined(HAVE_TARGET_32_LITTLE) || defined(HAVE_TARGET_32_BIG) + case Parameters::TARGET_32_LITTLE: + case Parameters::TARGET_32_BIG: + { + // This cast is ugly. We don't want to put a + // virtual method in Symbol, because we want Symbol + // to be as small as possible. + Sized_symbol<32>::Value_type v; + v = static_cast*>(gsym)->value(); + val = convert_types::Value_type>(v); + } + break; +#endif +#if defined(HAVE_TARGET_64_LITTLE) || defined(HAVE_TARGET_64_BIG) + case Parameters::TARGET_64_LITTLE: + case Parameters::TARGET_64_BIG: + { + Sized_symbol<64>::Value_type v; + v = static_cast*>(gsym)->value(); + val = convert_types::Value_type>(v); + } + break; +#endif + default: + gold_unreachable(); + } + if (this->use_plt_or_tls_offset_ + && gsym->type() == elfcpp::STT_TLS) val += parameters->target().tls_offset_for_global(gsym, got_indx); } @@ -1414,10 +1437,9 @@ Output_data_got::Got_e default: { - const Sized_relobj_file* object - = static_cast*>(this->u_.object); + const Relobj* object = this->u_.object; const unsigned int lsi = this->local_sym_index_; - bool is_tls = object->local_symbol(lsi)->is_tls_symbol(); + bool is_tls = object->local_is_tls(lsi); if (this->use_plt_or_tls_offset_ && !is_tls) { uint64_t plt_address = @@ -1436,7 +1458,7 @@ Output_data_got::Got_e break; } - elfcpp::Swap::writeval(pov, val); + elfcpp::Swap::writeval(pov, val); } // Output_data_got methods. @@ -1445,9 +1467,9 @@ Output_data_got::Got_e // this is a new GOT entry, false if the symbol already had a GOT // entry. -template +template bool -Output_data_got::add_global( +Output_data_got::add_global( Symbol* gsym, unsigned int got_type) { @@ -1461,10 +1483,10 @@ Output_data_got::add_g // Like add_global, but use the PLT offset. -template +template bool -Output_data_got::add_global_plt(Symbol* gsym, - unsigned int got_type) +Output_data_got::add_global_plt(Symbol* gsym, + unsigned int got_type) { if (gsym->has_got_offset(got_type)) return false; @@ -1477,9 +1499,9 @@ Output_data_got::add_g // Add an entry for a global symbol to the GOT, and add a dynamic // relocation of type R_TYPE for the GOT entry. -template +template void -Output_data_got::add_global_with_rel( +Output_data_got::add_global_with_rel( Symbol* gsym, unsigned int got_type, Output_data_reloc_generic* rel_dyn, @@ -1496,9 +1518,9 @@ Output_data_got::add_g // Add a pair of entries for a global symbol to the GOT, and add // dynamic relocations of type R_TYPE_1 and R_TYPE_2, respectively. // If R_TYPE_2 == 0, add the second entry with no relocation. -template +template void -Output_data_got::add_global_pair_with_rel( +Output_data_got::add_global_pair_with_rel( Symbol* gsym, unsigned int got_type, Output_data_reloc_generic* rel_dyn, @@ -1514,16 +1536,16 @@ Output_data_got::add_g if (r_type_2 != 0) rel_dyn->add_global_generic(gsym, r_type_2, this, - got_offset + size / 8, 0); + got_offset + got_size / 8, 0); } // Add an entry for a local symbol to the GOT. This returns true if // this is a new GOT entry, false if the symbol already has a GOT // entry. -template +template bool -Output_data_got::add_local( +Output_data_got::add_local( Relobj* object, unsigned int symndx, unsigned int got_type) @@ -1539,9 +1561,9 @@ Output_data_got::add_l // Like add_local, but use the PLT offset. -template +template bool -Output_data_got::add_local_plt( +Output_data_got::add_local_plt( Relobj* object, unsigned int symndx, unsigned int got_type) @@ -1558,9 +1580,9 @@ Output_data_got::add_l // Add an entry for a local symbol to the GOT, and add a dynamic // relocation of type R_TYPE for the GOT entry. -template +template void -Output_data_got::add_local_with_rel( +Output_data_got::add_local_with_rel( Relobj* object, unsigned int symndx, unsigned int got_type, @@ -1580,9 +1602,9 @@ Output_data_got::add_l // the output section to which input section SHNDX maps, on the first. // The first got entry will have a value of zero, the second the // value of the local symbol. -template +template void -Output_data_got::add_local_pair_with_rel( +Output_data_got::add_local_pair_with_rel( Relobj* object, unsigned int symndx, unsigned int shndx, @@ -1605,9 +1627,9 @@ Output_data_got::add_l // a dynamic relocation of type R_TYPE using STN_UNDEF on the first. // The first got entry will have a value of zero, the second the // value of the local symbol offset by Target::tls_offset_for_local. -template +template void -Output_data_got::add_local_tls_pair( +Output_data_got::add_local_tls_pair( Relobj* object, unsigned int symndx, unsigned int got_type, @@ -1626,9 +1648,9 @@ Output_data_got::add_l // Reserve a slot in the GOT for a local symbol or the second slot of a pair. -template +template void -Output_data_got::reserve_local( +Output_data_got::reserve_local( unsigned int i, Relobj* object, unsigned int sym_index, @@ -1640,9 +1662,9 @@ Output_data_got::reser // Reserve a slot in the GOT for a global symbol. -template +template void -Output_data_got::reserve_global( +Output_data_got::reserve_global( unsigned int i, Symbol* gsym, unsigned int got_type) @@ -1653,11 +1675,11 @@ Output_data_got::reser // Write out the GOT. -template +template void -Output_data_got::do_write(Output_file* of) +Output_data_got::do_write(Output_file* of) { - const int add = size / 8; + const int add = got_size / 8; const off_t off = this->offset(); const off_t oview_size = this->data_size(); @@ -1680,9 +1702,9 @@ Output_data_got::do_wr // Create a new GOT entry and return its offset. -template +template unsigned int -Output_data_got::add_got_entry(Got_entry got_entry) +Output_data_got::add_got_entry(Got_entry got_entry) { if (!this->is_data_size_valid()) { @@ -1693,11 +1715,12 @@ Output_data_got::add_g else { // For an incremental update, find an available slot. - off_t got_offset = this->free_list_.allocate(size / 8, size / 8, 0); + off_t got_offset = this->free_list_.allocate(got_size / 8, + got_size / 8, 0); if (got_offset == -1) gold_fallback(_("out of patch space (GOT);" " relink with --incremental-full")); - unsigned int got_index = got_offset / (size / 8); + unsigned int got_index = got_offset / (got_size / 8); gold_assert(got_index < this->entries_.size()); this->entries_[got_index] = got_entry; return static_cast(got_offset); @@ -1706,10 +1729,11 @@ Output_data_got::add_g // Create a pair of new GOT entries and return the offset of the first. -template +template unsigned int -Output_data_got::add_got_entry_pair(Got_entry got_entry_1, - Got_entry got_entry_2) +Output_data_got::add_got_entry_pair( + Got_entry got_entry_1, + Got_entry got_entry_2) { if (!this->is_data_size_valid()) { @@ -1723,11 +1747,12 @@ Output_data_got::add_g else { // For an incremental update, find an available pair of slots. - off_t got_offset = this->free_list_.allocate(2 * size / 8, size / 8, 0); + off_t got_offset = this->free_list_.allocate(2 * got_size / 8, + got_size / 8, 0); if (got_offset == -1) gold_fallback(_("out of patch space (GOT);" " relink with --incremental-full")); - unsigned int got_index = got_offset / (size / 8); + unsigned int got_index = got_offset / (got_size / 8); gold_assert(got_index < this->entries_.size()); this->entries_[got_index] = got_entry_1; this->entries_[got_index + 1] = got_entry_2; @@ -1737,9 +1762,9 @@ Output_data_got::add_g // Replace GOT entry I with a new value. -template +template void -Output_data_got::replace_got_entry( +Output_data_got::replace_got_entry( unsigned int i, Got_entry got_entry) { @@ -5442,24 +5467,16 @@ template class Output_data_group<64, true>; #endif -#ifdef HAVE_TARGET_32_LITTLE template class Output_data_got<32, false>; -#endif -#ifdef HAVE_TARGET_32_BIG template class Output_data_got<32, true>; -#endif -#ifdef HAVE_TARGET_64_LITTLE template class Output_data_got<64, false>; -#endif -#ifdef HAVE_TARGET_64_BIG template class Output_data_got<64, true>; -#endif } // End namespace gold.