2011-12-16 H.J. Lu PR gold/13507 * arm.cc (Arm_output_data_got): Pass 32 to Output_data_got constructor as got_entry_size. * i386.cc (Target_i386::got_section): Likewise. (Target_i386::got_section): Likewise. * output.cc (write): Add a parameter, got_entry_size, and use it to write GOT entry. (add_global_pair_with_rel) Replace size with this->got_entry_size_. (add_global_pair_with_rela): Likewise. (add_local_pair_with_rel): Likewise. (add_local_pair_with_rela): Likewise. (add_got_entry): Likewise. (add_got_entry_pair): Likewise. (do_write): Likewise. Pass this->got_entry_size_ to write. * output.h (Output_data_got): Add a parameter, got_entry_size, to constructor. Replace size with with got_entry_size. (reserve_slot): Replace size with this->got_entry_size_. (got_offset): Likewise. (write): Add parameter, got_entry_size. (got_entry_size_): New. * powerpc.cc (got_section): Pass size to Output_data_got constructor as got_entry_size. * sparc.cc (got_section): Likewise. * x86_64.cc (got_section): Pass 64 to Output_data_got constructor as got_entry_size. (init_got_plt_for_update): Likewise. diff --git a/gold/arm.cc b/gold/arm.cc index 72c3670..55b7595 100644 --- a/gold/arm.cc +++ b/gold/arm.cc @@ -1898,7 +1898,7 @@ class Arm_output_data_got : public Output_data_got<32, big_endian> { public: Arm_output_data_got(Symbol_table* symtab, Layout* layout) - : Output_data_got<32, big_endian>(), symbol_table_(symtab), layout_(layout) + : Output_data_got<32, big_endian>(32), symbol_table_(symtab), layout_(layout) { } // Add a static entry for the GOT entry at OFFSET. GSYM is a global diff --git a/gold/i386.cc b/gold/i386.cc index 191a915..a21cd68 100644 --- a/gold/i386.cc +++ b/gold/i386.cc @@ -713,7 +713,7 @@ Target_i386::got_section(Symbol_table* symtab, Layout* layout) { gold_assert(symtab != NULL && layout != NULL); - this->got_ = new Output_data_got<32, false>(); + this->got_ = new Output_data_got<32, false>(32); // When using -z now, we can treat .got.plt as a relro section. // Without -z now, it is modified after program startup by lazy @@ -768,7 +768,7 @@ Target_i386::got_section(Symbol_table* symtab, Layout* layout) // If there are any TLSDESC relocations, they get GOT entries in // .got.plt after the jump slot entries. - this->got_tlsdesc_ = new Output_data_got<32, false>(); + this->got_tlsdesc_ = new Output_data_got<32, false>(32); layout->add_output_section_data(".got.plt", elfcpp::SHT_PROGBITS, (elfcpp::SHF_ALLOC | elfcpp::SHF_WRITE), diff --git a/gold/output.cc b/gold/output.cc index 7633c73..f3725e3 100644 --- a/gold/output.cc +++ b/gold/output.cc @@ -1347,7 +1347,8 @@ Output_data_group::do_write(Output_file* of) template void -Output_data_got::Got_entry::write(unsigned char* pov) const +Output_data_got::Got_entry::write(unsigned int got_entry_size, + unsigned char* pov) const { Valtype val = 0; @@ -1402,7 +1403,17 @@ Output_data_got::Got_entry::write(unsigned char* pov) const break; } - elfcpp::Swap::writeval(pov, val); + switch (got_entry_size) + { + case 4: + elfcpp::Swap<32, big_endian>::writeval(pov, val); + break; + case 8: + elfcpp::Swap<64, big_endian>::writeval(pov, val); + break; + default: + gold_unreachable(); + } } // Output_data_got methods. @@ -1495,7 +1506,8 @@ Output_data_got::add_global_pair_with_rel( rel_dyn->add_global(gsym, r_type_1, this, got_offset); if (r_type_2 != 0) - rel_dyn->add_global(gsym, r_type_2, this, got_offset + size / 8); + rel_dyn->add_global(gsym, r_type_2, this, + got_offset + this->got_entry_size_); } template @@ -1515,7 +1527,8 @@ Output_data_got::add_global_pair_with_rela( rela_dyn->add_global(gsym, r_type_1, this, got_offset, 0); if (r_type_2 != 0) - rela_dyn->add_global(gsym, r_type_2, this, got_offset + size / 8, 0); + rela_dyn->add_global(gsym, r_type_2, this, + got_offset + this->got_entry_size_, 0); } // Add an entry for a local symbol to the GOT. This returns true if @@ -1618,7 +1631,8 @@ Output_data_got::add_local_pair_with_rel( rel_dyn->add_output_section(os, r_type_1, this, got_offset); if (r_type_2 != 0) - rel_dyn->add_output_section(os, r_type_2, this, got_offset + size / 8); + rel_dyn->add_output_section(os, r_type_2, this, + got_offset + this->got_entry_size_); } template @@ -1643,7 +1657,8 @@ Output_data_got::add_local_pair_with_rela( rela_dyn->add_output_section(os, r_type_1, this, got_offset, 0); if (r_type_2 != 0) - rela_dyn->add_output_section(os, r_type_2, this, got_offset + size / 8, 0); + rela_dyn->add_output_section(os, r_type_2, this, + got_offset + this->got_entry_size_, 0); } // Reserve a slot in the GOT for a local symbol or the second slot of a pair. @@ -1679,7 +1694,7 @@ template void Output_data_got::do_write(Output_file* of) { - const int add = size / 8; + const int add = this->got_entry_size_; const off_t off = this->offset(); const off_t oview_size = this->data_size(); @@ -1690,7 +1705,7 @@ Output_data_got::do_write(Output_file* of) p != this->entries_.end(); ++p) { - p->write(pov); + p->write(this->got_entry_size_, pov); pov += add; } @@ -1717,11 +1732,12 @@ Output_data_got::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(this->got_entry_size_, + this->got_entry_size_, 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 / this->got_entry_size_; gold_assert(got_index < this->entries_.size()); this->entries_[got_index] = got_entry; return static_cast(got_offset); @@ -1747,11 +1763,12 @@ Output_data_got::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 * this->got_entry_size_, + this->got_entry_size_, 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 / this->got_entry_size_; gold_assert(got_index < this->entries_.size()); this->entries_[got_index] = got_entry_1; this->entries_[got_index + 1] = got_entry_2; diff --git a/gold/output.h b/gold/output.h index e704213..81ca494 100644 --- a/gold/output.h +++ b/gold/output.h @@ -1983,19 +1983,19 @@ class Output_data_got : public Output_section_data_build typedef Output_data_reloc Rel_dyn; typedef Output_data_reloc Rela_dyn; - Output_data_got() - : Output_section_data_build(Output_data::default_alignment_for_size(size)), - entries_(), free_list_() + Output_data_got(int got_entry_size) + : Output_section_data_build(Output_data::default_alignment_for_size(got_entry_size)), + got_entry_size_(got_entry_size / 8), entries_(), free_list_() { } - Output_data_got(off_t data_size) + Output_data_got(int got_entry_size, off_t data_size) : Output_section_data_build(data_size, - Output_data::default_alignment_for_size(size)), - entries_(), free_list_() + Output_data::default_alignment_for_size(got_entry_size)), + got_entry_size_(got_entry_size / 8), entries_(), free_list_() { // For an incremental update, we have an existing GOT section. // Initialize the list of entries and the free list. - this->entries_.resize(data_size / (size / 8)); + this->entries_.resize(data_size / (got_entry_size / 8)); this->free_list_.init(data_size, false); } @@ -2083,7 +2083,8 @@ class Output_data_got : public Output_section_data_build // Reserve a slot in the GOT. void reserve_slot(unsigned int i) - { this->free_list_.remove(i * size / 8, (i + 1) * size / 8); } + { this->free_list_.remove(i * this->got_entry_size_, + (i + 1) * this->got_entry_size_); } // Reserve a slot in the GOT for a local symbol. void @@ -2139,7 +2140,7 @@ class Output_data_got : public Output_section_data_build // Write the GOT entry to an output view. void - write(unsigned char* pov) const; + write(unsigned int got_entry_size, unsigned char* pov) const; private: enum @@ -2178,7 +2179,7 @@ class Output_data_got : public Output_section_data_build // Return the offset into the GOT of GOT entry I. unsigned int got_offset(unsigned int i) const - { return i * (size / 8); } + { return i * this->got_entry_size_; } // Return the offset into the GOT of the last entry added. unsigned int @@ -2190,6 +2191,9 @@ class Output_data_got : public Output_section_data_build set_got_size() { this->set_current_data_size(this->got_offset(this->entries_.size())); } + // GOT entry size in bytes. + unsigned int got_entry_size_; + // The list of GOT entries. Got_entries entries_; diff --git a/gold/powerpc.cc b/gold/powerpc.cc index 62a17ca..948333f 100644 --- a/gold/powerpc.cc +++ b/gold/powerpc.cc @@ -765,7 +765,7 @@ Target_powerpc::got_section(Symbol_table* symtab, { gold_assert(symtab != NULL && layout != NULL); - this->got_ = new Output_data_got(); + this->got_ = new Output_data_got(size); layout->add_output_section_data(".got", elfcpp::SHT_PROGBITS, elfcpp::SHF_ALLOC | elfcpp::SHF_WRITE, diff --git a/gold/sparc.cc b/gold/sparc.cc index 12e1dee..4d88a86 100644 --- a/gold/sparc.cc +++ b/gold/sparc.cc @@ -1075,7 +1075,7 @@ Target_sparc::got_section(Symbol_table* symtab, { gold_assert(symtab != NULL && layout != NULL); - this->got_ = new Output_data_got(); + this->got_ = new Output_data_got(size); layout->add_output_section_data(".got", elfcpp::SHT_PROGBITS, (elfcpp::SHF_ALLOC diff --git a/gold/x86_64.cc b/gold/x86_64.cc index 0762926..5a7a807 100644 --- a/gold/x86_64.cc +++ b/gold/x86_64.cc @@ -849,7 +849,7 @@ Target_x86_64::got_section(Symbol_table* symtab, Layout* layout) ? ORDER_RELRO : ORDER_NON_RELRO_FIRST); - this->got_ = new Output_data_got<64, false>(); + this->got_ = new Output_data_got<64, false>(64); layout->add_output_section_data(".got", elfcpp::SHT_PROGBITS, (elfcpp::SHF_ALLOC @@ -893,7 +893,7 @@ Target_x86_64::got_section(Symbol_table* symtab, Layout* layout) // If there are any TLSDESC relocations, they get GOT entries in // .got.plt after the jump slot and IRELATIVE entries. - this->got_tlsdesc_ = new Output_data_got<64, false>(); + this->got_tlsdesc_ = new Output_data_got<64, false>(64); layout->add_output_section_data(".got.plt", elfcpp::SHT_PROGBITS, (elfcpp::SHF_ALLOC | elfcpp::SHF_WRITE), @@ -1471,7 +1471,7 @@ Target_x86_64::init_got_plt_for_update(Symbol_table* symtab, { gold_assert(this->got_ == NULL); - this->got_ = new Output_data_got<64, false>(got_count * 8); + this->got_ = new Output_data_got<64, false>(64, got_count * 8); layout->add_output_section_data(".got", elfcpp::SHT_PROGBITS, (elfcpp::SHF_ALLOC | elfcpp::SHF_WRITE), @@ -1499,7 +1499,7 @@ Target_x86_64::init_got_plt_for_update(Symbol_table* symtab, // If there are any TLSDESC relocations, they get GOT entries in // .got.plt after the jump slot entries. // FIXME: Get the count for TLSDESC entries. - this->got_tlsdesc_ = new Output_data_got<64, false>(0); + this->got_tlsdesc_ = new Output_data_got<64, false>(64, 0); layout->add_output_section_data(".got.plt", elfcpp::SHT_PROGBITS, elfcpp::SHF_ALLOC | elfcpp::SHF_WRITE, this->got_tlsdesc_,