diff options
author | Ian Lance Taylor <ian@airs.com> | 2012-09-12 18:29:18 +0000 |
---|---|---|
committer | Ian Lance Taylor <ian@airs.com> | 2012-09-12 18:29:18 +0000 |
commit | d77a055577382396ffb49b3b32c18198684f749f (patch) | |
tree | d387df11a6c7cf9f09f5c9ad216a2b76e0190187 | |
parent | f41aef5f6e10edcded9a747dc2bdc9832b940dc7 (diff) | |
download | gdb-d77a055577382396ffb49b3b32c18198684f749f.zip gdb-d77a055577382396ffb49b3b32c18198684f749f.tar.gz gdb-d77a055577382396ffb49b3b32c18198684f749f.tar.bz2 |
PR gold/14570
* output.cc: Rename Output_data_got template parameter from size
to got_size for all functions. Compile all variants of
Output_data_got.
(Output_data_got::Got_entry::write): Correct use of size for
symbol value. Use local_is_tls rather than casting to
Sized_relobj_file.
* object.h (class Object): Add local_is_tls and do_local_is_tls.
(class Sized_relobj_file): Add do_local_is_tls.
* incremental.h (class Sized_relobj_incr): Add do_local_is_tls.
-rw-r--r-- | gold/ChangeLog | 13 | ||||
-rw-r--r-- | gold/incremental.h | 6 | ||||
-rw-r--r-- | gold/object.h | 14 | ||||
-rw-r--r-- | gold/output.cc | 138 |
4 files changed, 110 insertions, 61 deletions
diff --git a/gold/ChangeLog b/gold/ChangeLog index ed1a8d4..9ad5a88 100644 --- a/gold/ChangeLog +++ b/gold/ChangeLog @@ -1,3 +1,16 @@ +2012-09-12 Ian Lance Taylor <iant@google.com> + + PR gold/14570 + * output.cc: Rename Output_data_got template parameter from size + to got_size for all functions. Compile all variants of + Output_data_got. + (Output_data_got::Got_entry::write): Correct use of size for + symbol value. Use local_is_tls rather than casting to + Sized_relobj_file. + * object.h (class Object): Add local_is_tls and do_local_is_tls. + (class Sized_relobj_file): Add do_local_is_tls. + * incremental.h (class Sized_relobj_incr): Add do_local_is_tls. + 2012-09-11 Alan Modra <amodra@gmail.com> PR gold/14566 diff --git a/gold/incremental.h b/gold/incremental.h index 20ae772..76d05af 100644 --- a/gold/incremental.h +++ b/gold/incremental.h @@ -1,6 +1,6 @@ // inremental.h -- incremental linking support for gold -*- C++ -*- -// Copyright 2009, 2010, 2011 Free Software Foundation, Inc. +// Copyright 2009, 2010, 2011, 2012 Free Software Foundation, Inc. // Written by Mikolaj Zalewski <mikolajz@google.com>. // This file is part of gold. @@ -1962,6 +1962,10 @@ class Sized_relobj_incr : public Sized_relobj<size, big_endian> 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 diff --git a/gold/object.h b/gold/object.h index 492ef63..a507204 100644 --- a/gold/object.h +++ b/gold/object.h @@ -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_relobj<size, big_endian> 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 diff --git a/gold/output.cc b/gold/output.cc index fa6d808..96fdd9f 100644 --- a/gold/output.cc +++ b/gold/output.cc @@ -1,6 +1,7 @@ // output.cc -- manage the output file for gold -// Copyright 2006, 2007, 2008, 2009, 2010, 2011 Free Software Foundation, Inc. +// Copyright 2006, 2007, 2008, 2009, 2010, 2011, 2012 +// Free Software Foundation, Inc. // Written by Ian Lance Taylor <iant@google.com>. // This file is part of gold. @@ -1367,9 +1368,9 @@ Output_data_group<size, big_endian>::do_write(Output_file* of) // Write out the entry. -template<int size, bool big_endian> +template<int got_size, bool big_endian> void -Output_data_got<size, big_endian>::Got_entry::write( +Output_data_got<got_size, big_endian>::Got_entry::write( unsigned int got_indx, unsigned char* pov) const { @@ -1388,13 +1389,36 @@ Output_data_got<size, big_endian>::Got_entry::write( + gsym->plt_offset()); else { - Sized_symbol<size>* 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<Sized_symbol<size>*>(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<Sized_symbol<32>*>(gsym)->value(); + val = convert_types<Valtype, Sized_symbol<32>::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<Sized_symbol<64>*>(gsym)->value(); + val = convert_types<Valtype, Sized_symbol<64>::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 +1438,9 @@ Output_data_got<size, big_endian>::Got_entry::write( default: { - const Sized_relobj_file<size, big_endian>* object - = static_cast<Sized_relobj_file<size, big_endian>*>(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 +1459,7 @@ Output_data_got<size, big_endian>::Got_entry::write( break; } - elfcpp::Swap<size, big_endian>::writeval(pov, val); + elfcpp::Swap<got_size, big_endian>::writeval(pov, val); } // Output_data_got methods. @@ -1445,9 +1468,9 @@ Output_data_got<size, big_endian>::Got_entry::write( // this is a new GOT entry, false if the symbol already had a GOT // entry. -template<int size, bool big_endian> +template<int got_size, bool big_endian> bool -Output_data_got<size, big_endian>::add_global( +Output_data_got<got_size, big_endian>::add_global( Symbol* gsym, unsigned int got_type) { @@ -1461,10 +1484,10 @@ Output_data_got<size, big_endian>::add_global( // Like add_global, but use the PLT offset. -template<int size, bool big_endian> +template<int got_size, bool big_endian> bool -Output_data_got<size, big_endian>::add_global_plt(Symbol* gsym, - unsigned int got_type) +Output_data_got<got_size, big_endian>::add_global_plt(Symbol* gsym, + unsigned int got_type) { if (gsym->has_got_offset(got_type)) return false; @@ -1477,9 +1500,9 @@ Output_data_got<size, big_endian>::add_global_plt(Symbol* gsym, // Add an entry for a global symbol to the GOT, and add a dynamic // relocation of type R_TYPE for the GOT entry. -template<int size, bool big_endian> +template<int got_size, bool big_endian> void -Output_data_got<size, big_endian>::add_global_with_rel( +Output_data_got<got_size, big_endian>::add_global_with_rel( Symbol* gsym, unsigned int got_type, Output_data_reloc_generic* rel_dyn, @@ -1496,9 +1519,9 @@ Output_data_got<size, big_endian>::add_global_with_rel( // 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<int size, bool big_endian> +template<int got_size, bool big_endian> void -Output_data_got<size, big_endian>::add_global_pair_with_rel( +Output_data_got<got_size, big_endian>::add_global_pair_with_rel( Symbol* gsym, unsigned int got_type, Output_data_reloc_generic* rel_dyn, @@ -1514,16 +1537,16 @@ Output_data_got<size, big_endian>::add_global_pair_with_rel( 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<int size, bool big_endian> +template<int got_size, bool big_endian> bool -Output_data_got<size, big_endian>::add_local( +Output_data_got<got_size, big_endian>::add_local( Relobj* object, unsigned int symndx, unsigned int got_type) @@ -1539,9 +1562,9 @@ Output_data_got<size, big_endian>::add_local( // Like add_local, but use the PLT offset. -template<int size, bool big_endian> +template<int got_size, bool big_endian> bool -Output_data_got<size, big_endian>::add_local_plt( +Output_data_got<got_size, big_endian>::add_local_plt( Relobj* object, unsigned int symndx, unsigned int got_type) @@ -1558,9 +1581,9 @@ Output_data_got<size, big_endian>::add_local_plt( // Add an entry for a local symbol to the GOT, and add a dynamic // relocation of type R_TYPE for the GOT entry. -template<int size, bool big_endian> +template<int got_size, bool big_endian> void -Output_data_got<size, big_endian>::add_local_with_rel( +Output_data_got<got_size, big_endian>::add_local_with_rel( Relobj* object, unsigned int symndx, unsigned int got_type, @@ -1580,9 +1603,9 @@ Output_data_got<size, big_endian>::add_local_with_rel( // 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<int size, bool big_endian> +template<int got_size, bool big_endian> void -Output_data_got<size, big_endian>::add_local_pair_with_rel( +Output_data_got<got_size, big_endian>::add_local_pair_with_rel( Relobj* object, unsigned int symndx, unsigned int shndx, @@ -1605,9 +1628,9 @@ Output_data_got<size, big_endian>::add_local_pair_with_rel( // 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<int size, bool big_endian> +template<int got_size, bool big_endian> void -Output_data_got<size, big_endian>::add_local_tls_pair( +Output_data_got<got_size, big_endian>::add_local_tls_pair( Relobj* object, unsigned int symndx, unsigned int got_type, @@ -1626,9 +1649,9 @@ Output_data_got<size, big_endian>::add_local_tls_pair( // Reserve a slot in the GOT for a local symbol or the second slot of a pair. -template<int size, bool big_endian> +template<int got_size, bool big_endian> void -Output_data_got<size, big_endian>::reserve_local( +Output_data_got<got_size, big_endian>::reserve_local( unsigned int i, Relobj* object, unsigned int sym_index, @@ -1640,9 +1663,9 @@ Output_data_got<size, big_endian>::reserve_local( // Reserve a slot in the GOT for a global symbol. -template<int size, bool big_endian> +template<int got_size, bool big_endian> void -Output_data_got<size, big_endian>::reserve_global( +Output_data_got<got_size, big_endian>::reserve_global( unsigned int i, Symbol* gsym, unsigned int got_type) @@ -1653,11 +1676,11 @@ Output_data_got<size, big_endian>::reserve_global( // Write out the GOT. -template<int size, bool big_endian> +template<int got_size, bool big_endian> void -Output_data_got<size, big_endian>::do_write(Output_file* of) +Output_data_got<got_size, big_endian>::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 +1703,9 @@ Output_data_got<size, big_endian>::do_write(Output_file* of) // Create a new GOT entry and return its offset. -template<int size, bool big_endian> +template<int got_size, bool big_endian> unsigned int -Output_data_got<size, big_endian>::add_got_entry(Got_entry got_entry) +Output_data_got<got_size, big_endian>::add_got_entry(Got_entry got_entry) { if (!this->is_data_size_valid()) { @@ -1693,11 +1716,12 @@ Output_data_got<size, big_endian>::add_got_entry(Got_entry got_entry) 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<unsigned int>(got_offset); @@ -1706,10 +1730,11 @@ Output_data_got<size, big_endian>::add_got_entry(Got_entry got_entry) // Create a pair of new GOT entries and return the offset of the first. -template<int size, bool big_endian> +template<int got_size, bool big_endian> unsigned int -Output_data_got<size, big_endian>::add_got_entry_pair(Got_entry got_entry_1, - Got_entry got_entry_2) +Output_data_got<got_size, big_endian>::add_got_entry_pair( + Got_entry got_entry_1, + Got_entry got_entry_2) { if (!this->is_data_size_valid()) { @@ -1723,11 +1748,12 @@ Output_data_got<size, big_endian>::add_got_entry_pair(Got_entry got_entry_1, 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 +1763,9 @@ Output_data_got<size, big_endian>::add_got_entry_pair(Got_entry got_entry_1, // Replace GOT entry I with a new value. -template<int size, bool big_endian> +template<int got_size, bool big_endian> void -Output_data_got<size, big_endian>::replace_got_entry( +Output_data_got<got_size, big_endian>::replace_got_entry( unsigned int i, Got_entry got_entry) { @@ -5442,24 +5468,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. |