aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDavid S. Miller <davem@redhat.com>2010-02-09 20:29:44 +0000
committerDavid S. Miller <davem@redhat.com>2010-02-09 20:29:44 +0000
commit612a8d3dbf065f5fbaf7d9fe094a252ea6eb6c17 (patch)
tree4c383e3823597ab1d18e73ed5dd49a0539f07b4e
parent684b268abacfb21ae5b35b2bb6d8fc24665e97d9 (diff)
downloadbinutils-612a8d3dbf065f5fbaf7d9fe094a252ea6eb6c17.zip
binutils-612a8d3dbf065f5fbaf7d9fe094a252ea6eb6c17.tar.gz
binutils-612a8d3dbf065f5fbaf7d9fe094a252ea6eb6c17.tar.bz2
* output.h (Output_data_dynamic::add_section_size): New method
that takes two Output_data objects. (Output_data_dynamic::Dynamic_entry): Create storage for secondary entry param. Handle it in initializers. * output.cc (Output_data_dynamic::Dynamic_entry::write): For DYNAMIC_SECTION_SIZE, add in second object size if non-NULL. * layout.h (Layout::add_target_dynamic_tags): Add dynrel_includes_plt arg. * layout.cc (Layout::add_target_dynamic_tags): If dynrel_includes_plt, and .rela.plt exists, set DT_REL{,A}SZ to sum of .rela.dyn and .rela.plt * arm.cc (Target_arm::do_finalize_sections): Update to pass false for dynrel_includes_plt. * i386.cc (Target_i386::do_finalize_sections): Likewise. * x86_64.cc (Target_x86_64::do_finalize_sections): Likewise. * sparc.cc (Target_sparc::make_plt_entry): Force .rela.dyn to be output before .rela.plt (Target_sparc::do_finalize_sections): Update to pass true for dynrel_includes_plt. * powerpc.cc (Target_powerpc::make_plt_entry): Force .rela.dyn to be output before .rela.plt (Target_powerpc::do_finalize_sections): Update to pass true for dynrel_includes_plt when 32-bit.
-rw-r--r--gold/ChangeLog23
-rw-r--r--gold/arm.cc2
-rw-r--r--gold/i386.cc2
-rw-r--r--gold/layout.cc10
-rw-r--r--gold/layout.h2
-rw-r--r--gold/output.cc2
-rw-r--r--gold/output.h22
-rw-r--r--gold/powerpc.cc7
-rw-r--r--gold/sparc.cc7
-rw-r--r--gold/x86_64.cc2
10 files changed, 69 insertions, 10 deletions
diff --git a/gold/ChangeLog b/gold/ChangeLog
index c2daecd..24b1b78 100644
--- a/gold/ChangeLog
+++ b/gold/ChangeLog
@@ -4,6 +4,29 @@
R_SPARC_RELATIVE using ->add_local_relative().
(Target_sparc::Scan::global): Likewise for ->add_global_relative().
+ * output.h (Output_data_dynamic::add_section_size): New method
+ that takes two Output_data objects.
+ (Output_data_dynamic::Dynamic_entry): Create storage for secondary
+ entry param. Handle it in initializers.
+ * output.cc (Output_data_dynamic::Dynamic_entry::write): For
+ DYNAMIC_SECTION_SIZE, add in second object size if non-NULL.
+ * layout.h (Layout::add_target_dynamic_tags): Add dynrel_includes_plt
+ arg.
+ * layout.cc (Layout::add_target_dynamic_tags): If dynrel_includes_plt,
+ and .rela.plt exists, set DT_REL{,A}SZ to sum of .rela.dyn and .rela.plt
+ * arm.cc (Target_arm::do_finalize_sections): Update to pass false
+ for dynrel_includes_plt.
+ * i386.cc (Target_i386::do_finalize_sections): Likewise.
+ * x86_64.cc (Target_x86_64::do_finalize_sections): Likewise.
+ * sparc.cc (Target_sparc::make_plt_entry): Force .rela.dyn to be output
+ before .rela.plt
+ (Target_sparc::do_finalize_sections): Update to pass true for
+ dynrel_includes_plt.
+ * powerpc.cc (Target_powerpc::make_plt_entry): Force .rela.dyn to be
+ output before .rela.plt
+ (Target_powerpc::do_finalize_sections): Update to pass true for
+ dynrel_includes_plt when 32-bit.
+
2010-02-08 Doug Kwan <dougkwan@google.com>
* arm.cc (Arm_relobj::simple_input_section_output_address): New
diff --git a/gold/arm.cc b/gold/arm.cc
index f121f93..902805c 100644
--- a/gold/arm.cc
+++ b/gold/arm.cc
@@ -7094,7 +7094,7 @@ Target_arm<big_endian>::do_finalize_sections(
? NULL
: this->plt_->rel_plt());
layout->add_target_dynamic_tags(true, this->got_plt_, rel_plt,
- this->rel_dyn_, true);
+ this->rel_dyn_, true, false);
// Emit any relocs we saved in an attempt to avoid generating COPY
// relocs.
diff --git a/gold/i386.cc b/gold/i386.cc
index 2eab3f8..f2a7b53 100644
--- a/gold/i386.cc
+++ b/gold/i386.cc
@@ -1609,7 +1609,7 @@ Target_i386::do_finalize_sections(
? NULL
: this->plt_->rel_plt());
layout->add_target_dynamic_tags(true, this->got_plt_, rel_plt,
- this->rel_dyn_, true);
+ this->rel_dyn_, true, false);
// Emit any relocs we saved in an attempt to avoid generating COPY
// relocs.
diff --git a/gold/layout.cc b/gold/layout.cc
index 52989a5..faa0c72 100644
--- a/gold/layout.cc
+++ b/gold/layout.cc
@@ -3240,7 +3240,7 @@ void
Layout::add_target_dynamic_tags(bool use_rel, const Output_data* plt_got,
const Output_data* plt_rel,
const Output_data_reloc_generic* dyn_rel,
- bool add_debug)
+ bool add_debug, bool dynrel_includes_plt)
{
Output_data_dynamic* odyn = this->dynamic_data_;
if (odyn == NULL)
@@ -3261,8 +3261,12 @@ Layout::add_target_dynamic_tags(bool use_rel, const Output_data* plt_got,
{
odyn->add_section_address(use_rel ? elfcpp::DT_REL : elfcpp::DT_RELA,
dyn_rel);
- odyn->add_section_size(use_rel ? elfcpp::DT_RELSZ : elfcpp::DT_RELASZ,
- dyn_rel);
+ if (plt_rel != NULL && dynrel_includes_plt)
+ odyn->add_section_size(use_rel ? elfcpp::DT_RELSZ : elfcpp::DT_RELASZ,
+ dyn_rel, plt_rel);
+ else
+ odyn->add_section_size(use_rel ? elfcpp::DT_RELSZ : elfcpp::DT_RELASZ,
+ dyn_rel);
const int size = parameters->target().get_size();
elfcpp::DT rel_tag;
int rel_size;
diff --git a/gold/layout.h b/gold/layout.h
index 15e7548..cd15c98 100644
--- a/gold/layout.h
+++ b/gold/layout.h
@@ -563,7 +563,7 @@ class Layout
add_target_dynamic_tags(bool use_rel, const Output_data* plt_got,
const Output_data* plt_rel,
const Output_data_reloc_generic* dyn_rel,
- bool add_debug);
+ bool add_debug, bool dynrel_includes_plt);
// Compute and write out the build ID if needed.
void
diff --git a/gold/output.cc b/gold/output.cc
index a8f03e7..4b34b8b 100644
--- a/gold/output.cc
+++ b/gold/output.cc
@@ -1560,6 +1560,8 @@ Output_data_dynamic::Dynamic_entry::write(
case DYNAMIC_SECTION_SIZE:
val = this->u_.od->data_size();
+ if (this->od2 != NULL)
+ val += this->od2->data_size();
break;
case DYNAMIC_SYMBOL:
diff --git a/gold/output.h b/gold/output.h
index 60d57de..a549b74 100644
--- a/gold/output.h
+++ b/gold/output.h
@@ -1997,6 +1997,12 @@ class Output_data_dynamic : public Output_section_data
add_section_size(elfcpp::DT tag, const Output_data* od)
{ this->add_entry(Dynamic_entry(tag, od, true)); }
+ // Add a new dynamic entry with the total size of two output datas.
+ void
+ add_section_size(elfcpp::DT tag, const Output_data* od,
+ const Output_data* od2)
+ { this->add_entry(Dynamic_entry(tag, od, od2)); }
+
// Add a new dynamic entry with the address of a symbol.
void
add_symbol(elfcpp::DT tag, const Symbol* sym)
@@ -2045,7 +2051,19 @@ class Output_data_dynamic : public Output_section_data
offset_(section_size
? DYNAMIC_SECTION_SIZE
: DYNAMIC_SECTION_ADDRESS)
- { this->u_.od = od; }
+ {
+ this->u_.od = od;
+ this->od2 = NULL;
+ }
+
+ // Create an entry with the size of two sections.
+ Dynamic_entry(elfcpp::DT tag, const Output_data* od, const Output_data* od2)
+ : tag_(tag),
+ offset_(DYNAMIC_SECTION_SIZE)
+ {
+ this->u_.od = od;
+ this->od2 = od2;
+ }
// Create an entry with the address of a section plus a constant offset.
Dynamic_entry(elfcpp::DT tag, const Output_data* od, unsigned int offset)
@@ -2101,6 +2119,8 @@ class Output_data_dynamic : public Output_section_data
// For DYNAMIC_STRING.
const char* str;
} u_;
+ // For DYNAMIC_SYMBOL with two sections.
+ const Output_data* od2;
// The dynamic tag.
elfcpp::DT tag_;
// The type of entry (Classification) or offset within a section.
diff --git a/gold/powerpc.cc b/gold/powerpc.cc
index 83bb992..cc46782 100644
--- a/gold/powerpc.cc
+++ b/gold/powerpc.cc
@@ -948,6 +948,11 @@ Target_powerpc<size, big_endian>::make_plt_entry(Symbol_table* symtab,
// Create the GOT section first.
this->got_section(symtab, layout);
+ // Ensure that .rela.dyn always appears before .rela.plt This is
+ // necessary due to how, on PowerPC and some other targets, .rela.dyn
+ // needs to include .rela.plt in it's range.
+ this->rela_dyn_section(layout);
+
this->plt_ = new Output_data_plt_powerpc<size, big_endian>(layout);
layout->add_output_section_data(".plt", elfcpp::SHT_PROGBITS,
(elfcpp::SHF_ALLOC
@@ -1556,7 +1561,7 @@ Target_powerpc<size, big_endian>::do_finalize_sections(
? NULL
: this->plt_->rel_plt());
layout->add_target_dynamic_tags(false, this->plt_, rel_plt,
- this->rela_dyn_, true);
+ this->rela_dyn_, true, size == 32);
// Emit any relocs we saved in an attempt to avoid generating COPY
// relocs.
diff --git a/gold/sparc.cc b/gold/sparc.cc
index 503cd8b..234c5f5 100644
--- a/gold/sparc.cc
+++ b/gold/sparc.cc
@@ -1369,6 +1369,11 @@ Target_sparc<size, big_endian>::make_plt_entry(Symbol_table* symtab,
// Create the GOT sections first.
this->got_section(symtab, layout);
+ // Ensure that .rela.dyn always appears before .rela.plt This is
+ // necessary due to how, on Sparc and some other targets, .rela.dyn
+ // needs to include .rela.plt in it's range.
+ this->rela_dyn_section(layout);
+
this->plt_ = new Output_data_plt_sparc<size, big_endian>(layout);
layout->add_output_section_data(".plt", elfcpp::SHT_PROGBITS,
(elfcpp::SHF_ALLOC
@@ -2338,7 +2343,7 @@ Target_sparc<size, big_endian>::do_finalize_sections(
? NULL
: this->plt_->rel_plt());
layout->add_target_dynamic_tags(false, this->plt_, rel_plt,
- this->rela_dyn_, true);
+ this->rela_dyn_, true, true);
// Emit any relocs we saved in an attempt to avoid generating COPY
// relocs.
diff --git a/gold/x86_64.cc b/gold/x86_64.cc
index 585a499..fea2ec9 100644
--- a/gold/x86_64.cc
+++ b/gold/x86_64.cc
@@ -1741,7 +1741,7 @@ Target_x86_64::do_finalize_sections(
? NULL
: this->plt_->rela_plt());
layout->add_target_dynamic_tags(false, this->got_plt_, rel_plt,
- this->rela_dyn_, true);
+ this->rela_dyn_, true, false);
// Fill in some more dynamic tags.
Output_data_dynamic* const odyn = layout->dynamic_data();