* output.h (class Output_data): Add const version of
authorIan Lance Taylor <ian@airs.com>
Thu, 7 Jan 2010 20:43:35 +0000 (20:43 +0000)
committerIan Lance Taylor <ian@airs.com>
Thu, 7 Jan 2010 20:43:35 +0000 (20:43 +0000)
output_section and do_output_section.
(class Output_section_data): Add const version of
do_output_section.
(class Output_section): Likewise.
* layout.cc (Layout::add_target_dynamic_tags): New function.
* layout.h (class Layout): Update declarations.
* arm.cc (Target_arm::do_finalize_sections): Use
add_target_dynamic_tags.
* i386.cc (Target_i386::do_finalize_sections): Likewise.
* powerpc.cc (Target_powerpc::do_finalize_sections): Likewise.
* sparc.cc (Target_sparc::do_finalize_sections): Likewise.
* x86_64.cc (Target_x86_64::do_finalize_sections): Likewise.

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

index b974662..a96d079 100644 (file)
@@ -1,5 +1,21 @@
 2010-01-07  Ian Lance Taylor  <iant@google.com>
 
+       * output.h (class Output_data): Add const version of
+       output_section and do_output_section.
+       (class Output_section_data): Add const version of
+       do_output_section.
+       (class Output_section): Likewise.
+       * layout.cc (Layout::add_target_dynamic_tags): New function.
+       * layout.h (class Layout): Update declarations.
+       * arm.cc (Target_arm::do_finalize_sections): Use
+       add_target_dynamic_tags.
+       * i386.cc (Target_i386::do_finalize_sections): Likewise.
+       * powerpc.cc (Target_powerpc::do_finalize_sections): Likewise.
+       * sparc.cc (Target_sparc::do_finalize_sections): Likewise.
+       * x86_64.cc (Target_x86_64::do_finalize_sections): Likewise.
+
+2010-01-07  Ian Lance Taylor  <iant@google.com>
+
        PR 11042
        * copy-relocs.cc (Copy_relocs::emit_copy_reloc): Mark the dynamic
        object as needed.
index b77adc7..087979b 100644 (file)
@@ -4868,39 +4868,11 @@ Target_arm<big_endian>::do_finalize_sections(
     this->set_may_use_blx(true);
  
   // Fill in some more dynamic tags.
-  Output_data_dynamic* const odyn = layout->dynamic_data();
-  if (odyn != NULL)
-    {
-      if (this->got_plt_ != NULL
-         && this->got_plt_->output_section() != NULL)
-       odyn->add_section_address(elfcpp::DT_PLTGOT, this->got_plt_);
-
-      if (this->plt_ != NULL
-         && this->plt_->output_section() != NULL)
-       {
-         const Output_data* od = this->plt_->rel_plt();
-         odyn->add_section_size(elfcpp::DT_PLTRELSZ, od);
-         odyn->add_section_address(elfcpp::DT_JMPREL, od);
-         odyn->add_constant(elfcpp::DT_PLTREL, elfcpp::DT_REL);
-       }
-
-      if (this->rel_dyn_ != NULL
-         && this->rel_dyn_->output_section() != NULL)
-       {
-         const Output_data* od = this->rel_dyn_;
-         odyn->add_section_address(elfcpp::DT_REL, od);
-         odyn->add_section_size(elfcpp::DT_RELSZ, od);
-         odyn->add_constant(elfcpp::DT_RELENT,
-                            elfcpp::Elf_sizes<32>::rel_size);
-       }
-
-      if (!parameters->options().shared())
-       {
-         // The value of the DT_DEBUG tag is filled in by the dynamic
-         // linker at run time, and used by the debugger.
-         odyn->add_constant(elfcpp::DT_DEBUG, 0);
-       }
-    }
+  const Reloc_section* rel_plt = (this->plt_ == NULL
+                                 ? NULL
+                                 : this->plt_->rel_plt());
+  layout->add_target_dynamic_tags(true, this->got_plt_, rel_plt,
+                                 this->rel_dyn_, true);
 
   // Emit any relocs we saved in an attempt to avoid generating COPY
   // relocs.
index 1044ad8..e1b32e7 100644 (file)
@@ -1565,40 +1565,11 @@ Target_i386::do_finalize_sections(
     const Input_objects*,
     Symbol_table* symtab)
 {
-  // Fill in some more dynamic tags.
-  Output_data_dynamic* const odyn = layout->dynamic_data();
-  if (odyn != NULL)
-    {
-      if (this->got_plt_ != NULL
-         && this->got_plt_->output_section() != NULL)
-       odyn->add_section_address(elfcpp::DT_PLTGOT, this->got_plt_);
-
-      if (this->plt_ != NULL
-         && this->plt_->output_section() != NULL)
-       {
-         const Output_data* od = this->plt_->rel_plt();
-         odyn->add_section_size(elfcpp::DT_PLTRELSZ, od);
-         odyn->add_section_address(elfcpp::DT_JMPREL, od);
-         odyn->add_constant(elfcpp::DT_PLTREL, elfcpp::DT_REL);
-       }
-
-      if (this->rel_dyn_ != NULL
-         && this->rel_dyn_->output_section() != NULL)
-       {
-         const Output_data* od = this->rel_dyn_;
-         odyn->add_section_address(elfcpp::DT_REL, od);
-         odyn->add_section_size(elfcpp::DT_RELSZ, od);
-         odyn->add_constant(elfcpp::DT_RELENT,
-                            elfcpp::Elf_sizes<32>::rel_size);
-       }
-
-      if (!parameters->options().shared())
-       {
-         // The value of the DT_DEBUG tag is filled in by the dynamic
-         // linker at run time, and used by the debugger.
-         odyn->add_constant(elfcpp::DT_DEBUG, 0);
-       }
-    }
+  const Reloc_section* rel_plt = (this->plt_ == NULL
+                                 ? NULL
+                                 : this->plt_->rel_plt());
+  layout->add_target_dynamic_tags(true, this->got_plt_, rel_plt,
+                                 this->rel_dyn_, true);
 
   // Emit any relocs we saved in an attempt to avoid generating COPY
   // relocs.
index 9f51e82..a55020c 100644 (file)
@@ -3206,6 +3206,83 @@ Layout::create_interp(const Target* target)
     }
 }
 
+// Add dynamic tags for the PLT and the dynamic relocs.  This is
+// called by the target-specific code.  This does nothing if not doing
+// a dynamic link.
+
+// USE_REL is true for REL relocs rather than RELA relocs.
+
+// If PLT_GOT is not NULL, then DT_PLTGOT points to it.
+
+// If PLT_REL is not NULL, it is used for DT_PLTRELSZ, and DT_JMPREL,
+// and we also set DT_PLTREL.
+
+// If DYN_REL is not NULL, it is used for DT_REL/DT_RELA,
+// DT_RELSZ/DT_RELASZ, DT_RELENT/DT_RELAENT.
+
+// If ADD_DEBUG is true, we add a DT_DEBUG entry when generating an
+// executable.
+
+void
+Layout::add_target_dynamic_tags(bool use_rel, const Output_data* plt_got,
+                               const Output_data* plt_rel,
+                               const Output_data* dyn_rel, bool add_debug)
+{
+  Output_data_dynamic* odyn = this->dynamic_data_;
+  if (odyn == NULL)
+    return;
+
+  if (plt_got != NULL && plt_got->output_section() != NULL)
+    odyn->add_section_address(elfcpp::DT_PLTGOT, plt_got);
+
+  if (plt_rel != NULL && plt_rel->output_section() != NULL)
+    {
+      odyn->add_section_size(elfcpp::DT_PLTRELSZ, plt_rel);
+      odyn->add_section_address(elfcpp::DT_JMPREL, plt_rel);
+      odyn->add_constant(elfcpp::DT_PLTREL,
+                        use_rel ? elfcpp::DT_REL : elfcpp::DT_RELA);
+    }
+
+  if (dyn_rel != NULL && dyn_rel->output_section() != NULL)
+    {
+      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);
+      const int size = parameters->target().get_size();
+      elfcpp::DT rel_tag;
+      int rel_size;
+      if (use_rel)
+       {
+         rel_tag = elfcpp::DT_RELENT;
+         if (size == 32)
+           rel_size = Reloc_types<elfcpp::SHT_REL, 32, false>::reloc_size;
+         else if (size == 64)
+           rel_size = Reloc_types<elfcpp::SHT_REL, 64, false>::reloc_size;
+         else
+           gold_unreachable();
+       }
+      else
+       {
+         rel_tag = elfcpp::DT_RELAENT;
+         if (size == 32)
+           rel_size = Reloc_types<elfcpp::SHT_RELA, 32, false>::reloc_size;
+         else if (size == 64)
+           rel_size = Reloc_types<elfcpp::SHT_RELA, 64, false>::reloc_size;
+         else
+           gold_unreachable();
+       }
+      odyn->add_constant(rel_tag, rel_size);
+    }
+
+  if (add_debug && !parameters->options().shared())
+    {
+      // The value of the DT_DEBUG tag is filled in by the dynamic
+      // linker at run time, and used by the debugger.
+      odyn->add_constant(elfcpp::DT_DEBUG, 0);
+    }
+}
+
 // Finish the .dynamic section and PT_DYNAMIC segment.
 
 void
index 604f19b..0b16cdf 100644 (file)
@@ -556,6 +556,13 @@ class Layout
   incremental_inputs()
   { return this->incremental_inputs_; }
 
+  // For the target-specific code to add dynamic tags which are common
+  // to most targets.
+  void
+  add_target_dynamic_tags(bool use_rel, const Output_data* plt_got,
+                         const Output_data* plt_rel,
+                         const Output_data* dyn_rel, bool add_debug);
+
   // Compute and write out the build ID if needed.
   void
   write_build_id(Output_file*) const;
index 98132e9..18e0a9e 100644 (file)
@@ -206,6 +206,10 @@ class Output_data
   output_section()
   { return this->do_output_section(); }
 
+  const Output_section*
+  output_section() const
+  { return this->do_output_section(); }
+
   // Return the output section index, if there is an output section.
   unsigned int
   out_shndx() const
@@ -358,6 +362,10 @@ class Output_data
   do_output_section()
   { return NULL; }
 
+  virtual const Output_section*
+  do_output_section() const
+  { return NULL; }
+
   // Return the output section index, if there is an output section.
   virtual unsigned int
   do_out_shndx() const
@@ -746,6 +754,10 @@ class Output_section_data : public Output_data
   do_output_section()
   { return this->output_section_; }
 
+  const Output_section*
+  do_output_section() const
+  { return this->output_section_; }
+
   // Return the section index of the output section.
   unsigned int
   do_out_shndx() const;
@@ -2641,6 +2653,10 @@ class Output_section : public Output_data
   do_output_section()
   { return this; }
 
+  const Output_section*
+  do_output_section() const
+  { return this; }
+
   // Return the section index in the output file.
   unsigned int
   do_out_shndx() const
index f7e62e7..83bb992 100644 (file)
@@ -1552,37 +1552,11 @@ Target_powerpc<size, big_endian>::do_finalize_sections(
     Symbol_table*)
 {
   // Fill in some more dynamic tags.
-  Output_data_dynamic* const odyn = layout->dynamic_data();
-  if (odyn != NULL)
-    {
-      if (this->plt_ != NULL
-         && this->plt_->output_section() != NULL)
-       {
-         const Output_data* od = this->plt_->rel_plt();
-         odyn->add_section_size(elfcpp::DT_PLTRELSZ, od);
-         odyn->add_section_address(elfcpp::DT_JMPREL, od);
-         odyn->add_constant(elfcpp::DT_PLTREL, elfcpp::DT_RELA);
-
-         odyn->add_section_address(elfcpp::DT_PLTGOT, this->plt_);
-       }
-
-      if (this->rela_dyn_ != NULL
-         && this->rela_dyn_->output_section() != NULL)
-       {
-         const Output_data* od = this->rela_dyn_;
-         odyn->add_section_address(elfcpp::DT_RELA, od);
-         odyn->add_section_size(elfcpp::DT_RELASZ, od);
-         odyn->add_constant(elfcpp::DT_RELAENT,
-                            elfcpp::Elf_sizes<size>::rela_size);
-       }
-
-      if (!parameters->options().shared())
-       {
-         // The value of the DT_DEBUG tag is filled in by the dynamic
-         // linker at run time, and used by the debugger.
-         odyn->add_constant(elfcpp::DT_DEBUG, 0);
-       }
-    }
+  const Reloc_section* rel_plt = (this->plt_ == NULL
+                                 ? NULL
+                                 : this->plt_->rel_plt());
+  layout->add_target_dynamic_tags(false, this->plt_, rel_plt,
+                                 this->rela_dyn_, true);
 
   // Emit any relocs we saved in an attempt to avoid generating COPY
   // relocs.
index 841db2f..c5ce06a 100644 (file)
@@ -2331,37 +2331,11 @@ Target_sparc<size, big_endian>::do_finalize_sections(
     Symbol_table*)
 {
   // Fill in some more dynamic tags.
-  Output_data_dynamic* const odyn = layout->dynamic_data();
-  if (odyn != NULL)
-    {
-      if (this->plt_ != NULL
-         && this->plt_->output_section() != NULL)
-       {
-         const Output_data* od = this->plt_->rel_plt();
-         odyn->add_section_size(elfcpp::DT_PLTRELSZ, od);
-         odyn->add_section_address(elfcpp::DT_JMPREL, od);
-         odyn->add_constant(elfcpp::DT_PLTREL, elfcpp::DT_RELA);
-
-         odyn->add_section_address(elfcpp::DT_PLTGOT, this->plt_);
-       }
-
-      if (this->rela_dyn_ != NULL
-         && this->rela_dyn_->output_section() != NULL)
-       {
-         const Output_data* od = this->rela_dyn_;
-         odyn->add_section_address(elfcpp::DT_RELA, od);
-         odyn->add_section_size(elfcpp::DT_RELASZ, od);
-         odyn->add_constant(elfcpp::DT_RELAENT,
-                            elfcpp::Elf_sizes<size>::rela_size);
-       }
-
-      if (!parameters->options().shared())
-       {
-         // The value of the DT_DEBUG tag is filled in by the dynamic
-         // linker at run time, and used by the debugger.
-         odyn->add_constant(elfcpp::DT_DEBUG, 0);
-       }
-    }
+  const Reloc_section* rel_plt = (this->plt_ == NULL
+                                 ? NULL
+                                 : this->plt_->rel_plt());
+  layout->add_target_dynamic_tags(false, this->plt_, rel_plt,
+                                 this->rela_dyn_, true);
 
   // Emit any relocs we saved in an attempt to avoid generating COPY
   // relocs.
index a7e7a39..f0aade4 100644 (file)
@@ -1655,48 +1655,27 @@ Target_x86_64::do_finalize_sections(
     const Input_objects*,
     Symbol_table* symtab)
 {
+  const Reloc_section* rel_plt = (this->plt_ == NULL
+                                 ? NULL
+                                 : this->plt_->rel_plt());
+  layout->add_target_dynamic_tags(false, this->got_plt_, rel_plt,
+                                 this->rela_dyn_, true);
+                                 
   // Fill in some more dynamic tags.
   Output_data_dynamic* const odyn = layout->dynamic_data();
   if (odyn != NULL)
     {
-      if (this->got_plt_ != NULL
-         && this->got_plt_->output_section() != NULL)
-       odyn->add_section_address(elfcpp::DT_PLTGOT, this->got_plt_);
-
       if (this->plt_ != NULL
-         && this->plt_->output_section() != NULL)
-       {
-         const Output_data* od = this->plt_->rel_plt();
-         odyn->add_section_size(elfcpp::DT_PLTRELSZ, od);
-         odyn->add_section_address(elfcpp::DT_JMPREL, od);
-         odyn->add_constant(elfcpp::DT_PLTREL, elfcpp::DT_RELA);
-         if (this->plt_->has_tlsdesc_entry())
-           {
-              unsigned int plt_offset = this->plt_->get_tlsdesc_plt_offset();
-              unsigned int got_offset = this->plt_->get_tlsdesc_got_offset();
-              this->got_->finalize_data_size();
-              odyn->add_section_plus_offset(elfcpp::DT_TLSDESC_PLT,
-                                            this->plt_, plt_offset);
-              odyn->add_section_plus_offset(elfcpp::DT_TLSDESC_GOT,
-                                            this->got_, got_offset);
-           }
-       }
-
-      if (this->rela_dyn_ != NULL
-         && this->rela_dyn_->output_section() != NULL)
-       {
-         const Output_data* od = this->rela_dyn_;
-         odyn->add_section_address(elfcpp::DT_RELA, od);
-         odyn->add_section_size(elfcpp::DT_RELASZ, od);
-         odyn->add_constant(elfcpp::DT_RELAENT,
-                            elfcpp::Elf_sizes<64>::rela_size);
-       }
-
-      if (!parameters->options().shared())
+         && this->plt_->output_section() != NULL
+         && this->plt_->has_tlsdesc_entry())
        {
-         // The value of the DT_DEBUG tag is filled in by the dynamic
-         // linker at run time, and used by the debugger.
-         odyn->add_constant(elfcpp::DT_DEBUG, 0);
+         unsigned int plt_offset = this->plt_->get_tlsdesc_plt_offset();
+         unsigned int got_offset = this->plt_->get_tlsdesc_got_offset();
+         this->got_->finalize_data_size();
+         odyn->add_section_plus_offset(elfcpp::DT_TLSDESC_PLT,
+                                       this->plt_, plt_offset);
+         odyn->add_section_plus_offset(elfcpp::DT_TLSDESC_GOT,
+                                       this->got_, got_offset);
        }
     }