*** empty log message ***
[binutils-gdb.git] / gold / powerpc.cc
index f27a9f1a8157b10fb4626bebf2eff2abd1eeed2f..0eda0a9edfd64876e0a2d484fd5ceea4f96a66af 100644 (file)
@@ -183,6 +183,28 @@ class Target_powerpc : public Sized_target<size, big_endian>
           const elfcpp::Rela<size, big_endian>& reloc, unsigned int r_type,
           Symbol* gsym);
 
+    inline bool
+    local_reloc_may_be_function_pointer(Symbol_table* , Layout* ,
+                                       Target_powerpc* ,
+                                       Sized_relobj<size, big_endian>* ,
+                                       unsigned int ,
+                                       Output_section* ,
+                                       const elfcpp::Rela<size, big_endian>& ,
+                                       unsigned int ,
+                                       const elfcpp::Sym<size, big_endian>&)
+    { return false; }
+
+    inline bool
+    global_reloc_may_be_function_pointer(Symbol_table* , Layout* ,
+                                        Target_powerpc* ,
+                                        Sized_relobj<size, big_endian>* ,
+                                        unsigned int ,
+                                        Output_section* ,
+                                        const elfcpp::Rela<size,
+                                                           big_endian>& ,
+                                        unsigned int , Symbol*)
+    { return false; }
+
   private:
     static void
     unsupported_reloc_local(Sized_relobj<size, big_endian>*,
@@ -716,7 +738,7 @@ Target_powerpc<size, big_endian>::got_section(Symbol_table* symtab,
 
       layout->add_output_section_data(".got", elfcpp::SHT_PROGBITS,
                                      elfcpp::SHF_ALLOC | elfcpp::SHF_WRITE,
-                                     this->got_, false);
+                                     this->got_, false, false, false, false);
 
       // Create the GOT2 or TOC in the .got section.
       if (size == 32)
@@ -725,7 +747,8 @@ Target_powerpc<size, big_endian>::got_section(Symbol_table* symtab,
          layout->add_output_section_data(".got2", elfcpp::SHT_PROGBITS,
                                          elfcpp::SHF_ALLOC
                                          | elfcpp::SHF_WRITE,
-                                         this->got2_, false);
+                                         this->got2_, false, false, false,
+                                         false);
        }
       else
        {
@@ -733,7 +756,8 @@ Target_powerpc<size, big_endian>::got_section(Symbol_table* symtab,
          layout->add_output_section_data(".toc", elfcpp::SHT_PROGBITS,
                                          elfcpp::SHF_ALLOC
                                          | elfcpp::SHF_WRITE,
-                                         this->toc_, false);
+                                         this->toc_, false, false, false,
+                                         false);
        }
 
       // Define _GLOBAL_OFFSET_TABLE_ at the start of the .got section.
@@ -760,7 +784,8 @@ Target_powerpc<size, big_endian>::rela_dyn_section(Layout* layout)
       gold_assert(layout != NULL);
       this->rela_dyn_ = new Reloc_section(parameters->options().combreloc());
       layout->add_output_section_data(".rela.dyn", elfcpp::SHT_RELA,
-                                     elfcpp::SHF_ALLOC, this->rela_dyn_, true);
+                                     elfcpp::SHF_ALLOC, this->rela_dyn_, true,
+                                     false, false, false);
     }
   return this->rela_dyn_;
 }
@@ -820,7 +845,8 @@ Output_data_plt_powerpc<size, big_endian>::Output_data_plt_powerpc(Layout* layou
 {
   this->rel_ = new Reloc_section(false);
   layout->add_output_section_data(".rela.plt", elfcpp::SHT_RELA,
-                                 elfcpp::SHF_ALLOC, this->rel_, true);
+                                 elfcpp::SHF_ALLOC, this->rel_, true, false,
+                                 false, false);
 }
 
 template<int size, bool big_endian>
@@ -944,12 +970,17 @@ 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
                                       | elfcpp::SHF_EXECINSTR
                                       | elfcpp::SHF_WRITE),
-                                     this->plt_, false);
+                                     this->plt_, false, false, false, false);
 
       // Define _PROCEDURE_LINKAGE_TABLE_ at the start of the .plt section.
       symtab->define_in_output_data("_PROCEDURE_LINKAGE_TABLE_", NULL,
@@ -1512,7 +1543,8 @@ Target_powerpc<size, big_endian>::scan_relocs(
     Output_section* os = layout->add_output_section_data(".sdata", 0,
                                                         elfcpp::SHF_ALLOC
                                                         | elfcpp::SHF_WRITE,
-                                                        sdata, false);
+                                                        sdata, false,
+                                                        false, false, false);
     symtab->define_in_output_data("_SDA_BASE_", NULL,
                                  Symbol_table::PREDEFINED,
                                  os,
@@ -1547,37 +1579,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, size == 32);
 
   // Emit any relocs we saved in an attempt to avoid generating COPY
   // relocs.