diff options
Diffstat (limited to 'gold/output.cc')
-rw-r--r-- | gold/output.cc | 138 |
1 files changed, 78 insertions, 60 deletions
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. |