Print unattached sections in the link map.
[deliverable/binutils-gdb.git] / gold / reloc.cc
index dacab35f67252fc0c1fd8dc5056881dbcc6dd3d7..115ab375e4638176645fe10c2780794b8b3cacc7 100644 (file)
@@ -1,6 +1,6 @@
 // reloc.cc -- relocate input files for gold.
 
-// Copyright 2006, 2007, 2008, 2009, 2010, 2011 Free Software Foundation, Inc.
+// Copyright (C) 2006-2014 Free Software Foundation, Inc.
 // Written by Ian Lance Taylor <iant@google.com>.
 
 // This file is part of gold.
@@ -659,7 +659,7 @@ Sized_relobj_file<size, big_endian>::do_relocate(const Symbol_table* symtab,
   // section data to the output file.  The second one applies
   // relocations.
 
-  this->write_sections(pshdrs, of, &views);
+  this->write_sections(layout, pshdrs, of, &views);
 
   // To speed up relocations, we set up hash tables for fast lookup of
   // input offsets to output addresses.
@@ -678,6 +678,8 @@ Sized_relobj_file<size, big_endian>::do_relocate(const Symbol_table* symtab,
     {
       if (views[i].view != NULL)
        {
+         if (views[i].is_ctors_reverse_view)
+           this->reverse_words(views[i].view, views[i].view_size);
          if (!views[i].is_postprocessing_view)
            {
              if (views[i].is_input_output_view)
@@ -712,7 +714,8 @@ struct Read_multiple_compare
 
 template<int size, bool big_endian>
 void
-Sized_relobj_file<size, big_endian>::write_sections(const unsigned char* pshdrs,
+Sized_relobj_file<size, big_endian>::write_sections(const Layout* layout,
+                                                   const unsigned char* pshdrs,
                                                    Output_file* of,
                                                    Views* pviews)
 {
@@ -761,6 +764,7 @@ Sized_relobj_file<size, big_endian>::write_sections(const unsigned char* pshdrs,
          pvs->address = posd->address();
          pvs->is_input_output_view = false;
          pvs->is_postprocessing_view = false;
+         pvs->is_ctors_reverse_view = false;
 
          continue;
        }
@@ -875,6 +879,12 @@ Sized_relobj_file<size, big_endian>::write_sections(const unsigned char* pshdrs,
       pvs->view_size = view_size;
       pvs->is_input_output_view = output_offset == invalid_address;
       pvs->is_postprocessing_view = os->requires_postprocessing();
+      pvs->is_ctors_reverse_view =
+       (!parameters->options().relocatable()
+        && view_size > size / 8
+        && (strcmp(os->name(), ".init_array") == 0
+            || strcmp(os->name(), ".fini_array") == 0)
+        && layout->is_ctors_in_init_array(this, i));
     }
 
   // Actually read the data.
@@ -1004,9 +1014,14 @@ Sized_relobj_file<size, big_endian>::do_relocate_sections(
                                   output_offset == invalid_address,
                                   view, address, view_size, reloc_map);
          if (parameters->options().emit_relocs())
-           this->emit_relocs(&relinfo, i, sh_type, prelocs, reloc_count,
-                             os, output_offset, view, address, view_size,
-                             (*pviews)[i].view, (*pviews)[i].view_size);
+           {
+             Relocatable_relocs* rr = this->relocatable_relocs(i);
+             target->relocate_relocs(&relinfo, sh_type, prelocs, reloc_count,
+                                     os, output_offset, rr,
+                                     view, address, view_size,
+                                     (*pviews)[i].view,
+                                     (*pviews)[i].view_size);
+           }
          if (parameters->incremental())
            this->incremental_relocs_write(&relinfo, sh_type, prelocs,
                                           reloc_count, os, output_offset, of);
@@ -1014,84 +1029,15 @@ Sized_relobj_file<size, big_endian>::do_relocate_sections(
       else
        {
          Relocatable_relocs* rr = this->relocatable_relocs(i);
-         target->relocate_for_relocatable(&relinfo, sh_type, prelocs,
-                                          reloc_count, os, output_offset, rr,
-                                          view, address, view_size,
-                                          (*pviews)[i].view,
-                                          (*pviews)[i].view_size);
+         target->relocate_relocs(&relinfo, sh_type, prelocs, reloc_count,
+                                 os, output_offset, rr,
+                                 view, address, view_size,
+                                 (*pviews)[i].view,
+                                 (*pviews)[i].view_size);
        }
     }
 }
 
-// Emit the relocs for --emit-relocs.
-
-template<int size, bool big_endian>
-void
-Sized_relobj_file<size, big_endian>::emit_relocs(
-    const Relocate_info<size, big_endian>* relinfo,
-    unsigned int i,
-    unsigned int sh_type,
-    const unsigned char* prelocs,
-    size_t reloc_count,
-    Output_section* output_section,
-    typename elfcpp::Elf_types<size>::Elf_Addr offset_in_output_section,
-    unsigned char* view,
-    typename elfcpp::Elf_types<size>::Elf_Addr address,
-    section_size_type view_size,
-    unsigned char* reloc_view,
-    section_size_type reloc_view_size)
-{
-  if (sh_type == elfcpp::SHT_REL)
-    this->emit_relocs_reltype<elfcpp::SHT_REL>(relinfo, i, prelocs,
-                                              reloc_count, output_section,
-                                              offset_in_output_section,
-                                              view, address, view_size,
-                                              reloc_view, reloc_view_size);
-  else
-    {
-      gold_assert(sh_type == elfcpp::SHT_RELA);
-      this->emit_relocs_reltype<elfcpp::SHT_RELA>(relinfo, i, prelocs,
-                                                 reloc_count, output_section,
-                                                 offset_in_output_section,
-                                                 view, address, view_size,
-                                                 reloc_view, reloc_view_size);
-    }
-}
-
-// Emit the relocs for --emit-relocs, templatized on the type of the
-// relocation section.
-
-template<int size, bool big_endian>
-template<int sh_type>
-void
-Sized_relobj_file<size, big_endian>::emit_relocs_reltype(
-    const Relocate_info<size, big_endian>* relinfo,
-    unsigned int i,
-    const unsigned char* prelocs,
-    size_t reloc_count,
-    Output_section* output_section,
-    typename elfcpp::Elf_types<size>::Elf_Addr offset_in_output_section,
-    unsigned char* view,
-    typename elfcpp::Elf_types<size>::Elf_Addr address,
-    section_size_type view_size,
-    unsigned char* reloc_view,
-    section_size_type reloc_view_size)
-{
-  const Relocatable_relocs* rr = this->relocatable_relocs(i);
-  relocate_for_relocatable<size, big_endian, sh_type>(
-    relinfo,
-    prelocs,
-    reloc_count,
-    output_section,
-    offset_in_output_section,
-    rr,
-    view,
-    address,
-    view_size,
-    reloc_view,
-    reloc_view_size);
-}
-
 // Write the incremental relocs.
 
 template<int size, bool big_endian>
@@ -1483,6 +1429,26 @@ Sized_relobj_file<size, big_endian>::find_functions(
     }
 }
 
+// Reverse the words in a section.  Used for .ctors sections mapped to
+// .init_array sections.  See ctors_sections_in_init_array in
+// layout.cc.
+
+template<int size, bool big_endian>
+void
+Sized_relobj_file<size, big_endian>::reverse_words(unsigned char* view,
+                                                  section_size_type view_size)
+{
+  typedef typename elfcpp::Swap<size, big_endian>::Valtype Valtype;
+  Valtype* vview = reinterpret_cast<Valtype*>(view);
+  section_size_type vview_size = view_size / (size / 8);
+  for (section_size_type i = 0; i < vview_size / 2; ++i)
+    {
+      Valtype tmp = vview[i];
+      vview[i] = vview[vview_size - 1 - i];
+      vview[vview_size - 1 - i] = tmp;
+    }
+}
+
 // Class Merged_symbol_value.
 
 template<int size>
This page took 0.026671 seconds and 4 git commands to generate.