* output.h (Output_data_dynamic::add_section_size): New method
authorDavid S. Miller <davem@redhat.com>
Tue, 9 Feb 2010 20:29:44 +0000 (20:29 +0000)
committerDavid S. Miller <davem@redhat.com>
Tue, 9 Feb 2010 20:29:44 +0000 (20:29 +0000)
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.

gold/ChangeLog
gold/arm.cc
gold/i386.cc
gold/layout.cc
gold/layout.h
gold/output.cc
gold/output.h
gold/powerpc.cc
gold/sparc.cc
gold/x86_64.cc

index c2daecdd28171fa468dac0a31b3c7cbf3b3aab9e..24b1b7891550c8bca4991eafdde6372cb16e4805 100644 (file)
@@ -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
index f121f93fcf20757ab76e288a9c650c2732413d1c..902805c3956f0e60fb9fd658be41cad917916efd 100644 (file)
@@ -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.
index 2eab3f86c08c655ff026dccffac334d421d579c6..f2a7b53f7ad441b91038fd3b26a23311d0f3a0d1 100644 (file)
@@ -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.
index 52989a5b1a803cd2ab524605aa4f7874573de1ed..faa0c7252bcd5de50f42a1b20f5329578ffa36ac 100644 (file)
@@ -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;
index 15e75484b34e6465984f6deb31ef1abb21a51708..cd15c983e8b46a1c31f6776dbb29dbd8c8dde589 100644 (file)
@@ -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
index a8f03e7ec4cfd0d384e362151feeaff9a0ca5e54..4b34b8b70b6b022aec1c7256ba8ffad991f58933 100644 (file)
@@ -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:
index 60d57debfb830bfa476357ab7da76d905cd2dbea..a549b7435e8c41a56d339915f34037e0eaa10f14 100644 (file)
@@ -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.
index 83bb992b8a1271ef0b3ab4fea01a1c3bc4534d40..cc4678229e99c586e9ad91defbb56ba4de7827d1 100644 (file)
@@ -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.
index 503cd8bb6bd327cca0d50196f4cfd165170fe6df..234c5f5aa0aac0ba576ad4d703e22e67d7158778 100644 (file)
@@ -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.
index 585a49995eeda03542ba816b4de9e5a83538e03d..fea2ec9b914836fd41c7d1739e7b9ab4611b9f2b 100644 (file)
@@ -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();