This is the mail archive of the
binutils@sourceware.org
mailing list for the binutils project.
Re: PATCH: PR gold/13507: Gold assumes GOT entry size is the same as ELF class size
- From: "H.J. Lu" <hongjiu dot lu at intel dot com>
- To: binutils at sourceware dot org, Ian Lance Taylor <iant at google dot com>
- Date: Thu, 15 Dec 2011 19:19:29 -0800
- Subject: Re: PATCH: PR gold/13507: Gold assumes GOT entry size is the same as ELF class size
- References: <20111215230919.GA14342@intel.com>
- Reply-to: "H.J. Lu" <hjl dot tools at gmail dot com>
On Thu, Dec 15, 2011 at 03:09:19PM -0800, H.J. Lu wrote:
> Hi Ian,
>
> This patch adds a parameter, got_entry_size, to Output_data_got
> constructor so that a target can have a different GOT entry size.
> OK to install?
>
> Thanks.
>
>
<size> in
template<int size, bool big_endian>
class Output_data_got : public Output_section_data_build
{
is the ELF class size. That is why I added got_entry_size to
Output_data_got so that target can set its GOT entry size, independent
of the ELF class size.
Here is the updated patch to avoid "/ 8". Tested on Linux/x86-64.
OK to install?
Thanks.
H.J.
---
2011-12-15 H.J. Lu <hongjiu.lu@intel.com>
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 (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.
(do_write): Likewise.
(add_got_entry): Likewise.
(add_got_entry_pair): Likewise.
* 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.
(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..f1b1456 100644
--- a/gold/output.cc
+++ b/gold/output.cc
@@ -1495,7 +1495,8 @@ Output_data_got<size, big_endian>::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<int size, bool big_endian>
@@ -1515,7 +1516,8 @@ Output_data_got<size, big_endian>::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 +1620,8 @@ Output_data_got<size, big_endian>::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<int size, bool big_endian>
@@ -1643,7 +1646,8 @@ Output_data_got<size, big_endian>::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 +1683,7 @@ template<int size, bool big_endian>
void
Output_data_got<size, big_endian>::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();
@@ -1717,11 +1721,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(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<unsigned int>(got_offset);
@@ -1747,11 +1752,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 * 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..1c3544a 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<elfcpp::SHT_REL, true, size, big_endian> Rel_dyn;
typedef Output_data_reloc<elfcpp::SHT_RELA, true, size, big_endian> 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
@@ -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<size, big_endian>::got_section(Symbol_table* symtab,
{
gold_assert(symtab != NULL && layout != NULL);
- this->got_ = new Output_data_got<size, big_endian>();
+ this->got_ = new Output_data_got<size, big_endian>(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<size, big_endian>::got_section(Symbol_table* symtab,
{
gold_assert(symtab != NULL && layout != NULL);
- this->got_ = new Output_data_got<size, big_endian>();
+ this->got_ = new Output_data_got<size, big_endian>(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_,