PATCH: PR gold/13507: Gold assumes GOT entry size is the same as ELF class size
Cary Coutant
ccoutant@google.com
Tue Jan 3 23:24:00 GMT 2012
> Fundamentally the generic incremental linker code in incremental.cc is
> going to have to ask the target for the size of a GOT entry. That is
> true under any possible scheme. This could be done by making
> Output_data_got a virtual class, or via some other scheme.
This patch adds an abstract base class so that do_process_got_plt()
doesn't need to know the size of the GOT entries. OK to commit?
-cary
2012-01-03 Cary Coutant <ccoutant@google.com>
* gold/incremental.cc (Sized_incremental_binary::do_process_got_plt):
Use abstract base class for GOT.
* gold/output.h (class Output_data_got_base): New abstract base class.
(class Output_data_got): Derive from new base class, adjust ctors.
(Output_data_got::reserve_slot): Make virtual; rename to
do_reserve_slot; Adjust callers.
* gold/target.h (Sized_target::init_got_plt_for_update): Return
pointer to abstract base class.
* gold/x86_64.cc (Target_x86_64::init_got_plt_for_update): Likewise.
-------------- next part --------------
2012-01-03 Cary Coutant <ccoutant@google.com>
* gold/incremental.cc (Sized_incremental_binary::do_process_got_plt):
Use abstract base class for GOT.
* gold/output.h (class Output_data_got_base): New abstract base class.
(class Output_data_got): Derive from new base class, adjust ctors.
(Output_data_got::reserve_slot): Make virtual; rename to
do_reserve_slot; Adjust callers.
* gold/target.h (Sized_target::init_got_plt_for_update): Return
pointer to abstract base class.
* gold/x86_64.cc (Target_x86_64::init_got_plt_for_update): Likewise.
commit 5a692679e63392dc2d7dbeb74d666578d633cdd6
Author: Cary Coutant <ccoutant@google.com>
Date: Tue Jan 3 15:17:40 2012 -0800
Make size of GOT entry independent of ELF size.
diff --git a/gold/incremental.cc b/gold/incremental.cc
index 75e44c5..39bad37 100644
--- a/gold/incremental.cc
+++ b/gold/incremental.cc
@@ -632,7 +632,7 @@ Sized_incremental_binary<size, big_endian>::do_process_got_plt(
// Tell the target how big the GOT and PLT sections are.
unsigned int got_count = got_plt_reader.get_got_entry_count();
unsigned int plt_count = got_plt_reader.get_plt_entry_count();
- Output_data_got<size, big_endian>* got =
+ Output_data_got_base* got =
target->init_got_plt_for_update(symtab, layout, got_count, plt_count);
// Read the GOT entries from the base file and build the outgoing GOT.
diff --git a/gold/output.cc b/gold/output.cc
index 6e46fd5..ca19039 100644
--- a/gold/output.cc
+++ b/gold/output.cc
@@ -1582,7 +1582,7 @@ Output_data_got<size, big_endian>::reserve_local(
unsigned int sym_index,
unsigned int got_type)
{
- this->reserve_slot(i);
+ this->do_reserve_slot(i);
object->set_local_got_offset(sym_index, got_type, this->got_offset(i));
}
@@ -1595,7 +1595,7 @@ Output_data_got<size, big_endian>::reserve_global(
Symbol* gsym,
unsigned int got_type)
{
- this->reserve_slot(i);
+ this->do_reserve_slot(i);
gsym->set_got_offset(got_type, this->got_offset(i));
}
diff --git a/gold/output.h b/gold/output.h
index db38236..fa21b64 100644
--- a/gold/output.h
+++ b/gold/output.h
@@ -2151,20 +2151,42 @@ class Output_data_group : public Output_section_data
// needed. The GOT_SIZE template parameter is the size in bits of a
// GOT entry, typically 32 or 64.
+class Output_data_got_base : public Output_section_data_build
+{
+ public:
+ Output_data_got_base(uint64_t align)
+ : Output_section_data_build(align)
+ { }
+
+ Output_data_got_base(off_t data_size, uint64_t align)
+ : Output_section_data_build(data_size, align)
+ { }
+
+ // Reserve a slot in the GOT.
+ void
+ reserve_slot(unsigned int i)
+ { this->do_reserve_slot(i); }
+
+ protected:
+ // Reserve a slot in the GOT.
+ virtual void
+ do_reserve_slot(unsigned int i) = 0;
+};
+
template<int got_size, bool big_endian>
-class Output_data_got : public Output_section_data_build
+class Output_data_got : public Output_data_got_base
{
public:
typedef typename elfcpp::Elf_types<got_size>::Elf_Addr Valtype;
Output_data_got()
- : Output_section_data_build(Output_data::default_alignment_for_size(got_size)),
+ : Output_data_got_base(Output_data::default_alignment_for_size(got_size)),
entries_(), free_list_()
{ }
Output_data_got(off_t data_size)
- : Output_section_data_build(data_size,
- Output_data::default_alignment_for_size(got_size)),
+ : Output_data_got_base(data_size,
+ Output_data::default_alignment_for_size(got_size)),
entries_(), free_list_()
{
// For an incremental update, we have an existing GOT section.
@@ -2231,11 +2253,6 @@ class Output_data_got : public Output_section_data_build
return got_offset;
}
- // Reserve a slot in the GOT.
- void
- reserve_slot(unsigned int i)
- { this->free_list_.remove(i * got_size / 8, (i + 1) * got_size / 8); }
-
// Reserve a slot in the GOT for a local symbol.
void
reserve_local(unsigned int i, Relobj* object, unsigned int sym_index,
@@ -2255,6 +2272,11 @@ class Output_data_got : public Output_section_data_build
do_print_to_mapfile(Mapfile* mapfile) const
{ mapfile->print_output_data(this, _("** GOT")); }
+ // Reserve a slot in the GOT.
+ virtual void
+ do_reserve_slot(unsigned int i)
+ { this->free_list_.remove(i * got_size / 8, (i + 1) * got_size / 8); }
+
private:
// This POD class holds a single GOT entry.
class Got_entry
diff --git a/gold/target.h b/gold/target.h
index a378120..1035427 100644
--- a/gold/target.h
+++ b/gold/target.h
@@ -56,8 +56,7 @@ template<int size>
class Sized_symbol;
class Symbol_table;
class Output_data;
-template<int size, bool big_endian>
-class Output_data_got;
+class Output_data_got_base;
class Output_section;
class Input_objects;
class Task;
@@ -845,7 +844,7 @@ class Sized_target : public Target
// Create the GOT and PLT sections for an incremental update.
// A target needs to implement this to support incremental linking.
- virtual Output_data_got<size, big_endian>*
+ virtual Output_data_got_base*
init_got_plt_for_update(Symbol_table*,
Layout*,
unsigned int /* got_count */,
diff --git a/gold/x86_64.cc b/gold/x86_64.cc
index 552e9d1..eeb532b 100644
--- a/gold/x86_64.cc
+++ b/gold/x86_64.cc
@@ -425,7 +425,7 @@ class Target_x86_64 : public Sized_target<64, false>
plt_entry_size() const;
// Create the GOT section for an incremental update.
- Output_data_got<64, false>*
+ Output_data_got_base*
init_got_plt_for_update(Symbol_table* symtab,
Layout* layout,
unsigned int got_count,
@@ -1463,7 +1463,7 @@ Target_x86_64::plt_entry_size() const
// Create the GOT and PLT sections for an incremental update.
-Output_data_got<64, false>*
+Output_data_got_base*
Target_x86_64::init_got_plt_for_update(Symbol_table* symtab,
Layout* layout,
unsigned int got_count,
More information about the Binutils
mailing list