Fix wrong source file name of cross-arm-binutils.
[platform/upstream/binutils.git] / gold / object.cc
index fc8533e..e357ddf 100644 (file)
@@ -1,7 +1,6 @@
 // object.cc -- support for an object file for linking in gold
 
-// Copyright 2006, 2007, 2008, 2009, 2010, 2011, 2012
-// 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.
@@ -48,7 +47,8 @@ namespace gold
 
 // Struct Read_symbols_data.
 
-// Destroy any remaining File_view objects.
+// Destroy any remaining File_view objects and buffers of decompressed
+// sections.
 
 Read_symbols_data::~Read_symbols_data()
 {
@@ -330,9 +330,13 @@ Relobj::is_section_name_included(const char* name)
       || (is_prefix_of(".text", name)
          && strstr(name, "personality"))
       || (is_prefix_of(".data", name)
-         &&  strstr(name, "personality"))
+         && strstr(name, "personality"))
+      || (is_prefix_of(".sdata", name)
+         && strstr(name, "personality"))
       || (is_prefix_of(".gnu.linkonce.d", name)
-         && strstr(name, "personality")))
+         && strstr(name, "personality"))
+      || (is_prefix_of(".rodata", name)
+         && strstr(name, "nptl_version")))
     {
       return true;
     }
@@ -386,6 +390,23 @@ Sized_relobj<size, big_endian>::do_for_all_local_got_entries(
     }
 }
 
+// Get the address of an output section.
+
+template<int size, bool big_endian>
+uint64_t
+Sized_relobj<size, big_endian>::do_output_section_address(
+    unsigned int shndx)
+{
+  // If the input file is linked as --just-symbols, the output
+  // section address is the input section address.
+  if (this->just_symbols())
+    return this->section_address(shndx);
+
+  const Output_section* os = this->do_output_section(shndx);
+  gold_assert(os != NULL);
+  return os->address();
+}
+
 // Class Sized_relobj_file.
 
 template<int size, bool big_endian>
@@ -409,6 +430,7 @@ Sized_relobj_file<size, big_endian>::Sized_relobj_file(
     kept_comdat_sections_(),
     has_eh_frame_(false),
     discarded_eh_frame_shndx_(-1U),
+    is_deferred_layout_(false),
     deferred_layout_(),
     deferred_layout_relocs_(),
     compressed_sections_()
@@ -514,15 +536,16 @@ Sized_relobj_file<size, big_endian>::check_eh_frame_flags(
 
 template<int size, bool big_endian>
 const unsigned char*
-Sized_relobj_file<size, big_endian>::find_shdr(
+Object::find_shdr(
     const unsigned char* pshdrs,
     const char* name,
     const char* names,
     section_size_type names_size,
     const unsigned char* hdr) const
 {
+  const int shdr_size = elfcpp::Elf_sizes<size>::shdr_size;
   const unsigned int shnum = this->shnum();
-  const unsigned char* hdr_end = pshdrs + This::shdr_size * shnum;
+  const unsigned char* hdr_end = pshdrs + shdr_size * shnum;
   size_t sh_name = 0;
 
   while (1)
@@ -530,7 +553,7 @@ Sized_relobj_file<size, big_endian>::find_shdr(
       if (hdr)
        {
          // We found HDR last time we were called, continue looking.
-         typename This::Shdr shdr(hdr);
+         typename elfcpp::Shdr<size, big_endian> shdr(hdr);
          sh_name = shdr.get_sh_name();
        }
       else
@@ -554,13 +577,13 @@ Sized_relobj_file<size, big_endian>::find_shdr(
            return hdr;
        }
 
-      hdr += This::shdr_size;
+      hdr += shdr_size;
       while (hdr < hdr_end)
        {
-         typename This::Shdr shdr(hdr);
+         typename elfcpp::Shdr<size, big_endian> shdr(hdr);
          if (shdr.get_sh_name() == sh_name)
            return hdr;
-         hdr += This::shdr_size;
+         hdr += shdr_size;
        }
       hdr = NULL;
       if (sh_name == 0)
@@ -582,7 +605,8 @@ Sized_relobj_file<size, big_endian>::find_eh_frame(
 
   while (1)
     {
-      s = this->find_shdr(pshdrs, ".eh_frame", names, names_size, s);
+      s = this->template find_shdr<size, big_endian>(pshdrs, ".eh_frame",
+                                                    names, names_size, s);
       if (s == NULL)
        return false;
 
@@ -734,6 +758,16 @@ template<int size, bool big_endian>
 void
 Sized_relobj_file<size, big_endian>::do_read_symbols(Read_symbols_data* sd)
 {
+  this->base_read_symbols(sd);
+}
+
+// Read the sections and symbols from an object file.  This is common
+// code for all target-specific overrides of do_read_symbols().
+
+template<int size, bool big_endian>
+void
+Sized_relobj_file<size, big_endian>::base_read_symbols(Read_symbols_data* sd)
+{
   this->read_section_data(&this->elf_file_, sd);
 
   const unsigned char* const pshdrs = sd->section_headers->data();
@@ -1221,15 +1255,19 @@ Sized_relobj_file<size, big_endian>::layout_eh_frame_section(
 // whether they should be included in the link.  If they should, we
 // pass them to the Layout object, which will return an output section
 // and an offset.
-// During garbage collection (--gc-sections) and identical code folding
-// (--icf), this function is called twice.  When it is called the first
-// time, it is for setting up some sections as roots to a work-list for
-// --gc-sections and to do comdat processing.  Actual layout happens the
-// second time around after all the relevant sections have been determined.
-// The first time, is_worklist_ready or is_icf_ready is false. It is then
-// set to true after the garbage collection worklist or identical code
-// folding is processed and the relevant sections to be kept are
-// determined.  Then, this function is called again to layout the sections.
+// This function is called twice sometimes, two passes, when mapping
+// of input sections to output sections must be delayed.
+// This is true for the following :
+// * Garbage collection (--gc-sections): Some input sections will be
+// discarded and hence the assignment must wait until the second pass.
+// In the first pass,  it is for setting up some sections as roots to
+// a work-list for --gc-sections and to do comdat processing.
+// * Identical Code Folding (--icf=<safe,all>): Some input sections
+// will be folded and hence the assignment must wait.
+// * Using plugins to map some sections to unique segments: Mapping
+// some sections to unique segments requires mapping them to unique
+// output sections too.  This can be done via plugins now and this
+// information is not available in the first pass.
 
 template<int size, bool big_endian>
 void
@@ -1238,26 +1276,44 @@ Sized_relobj_file<size, big_endian>::do_layout(Symbol_table* symtab,
                                               Read_symbols_data* sd)
 {
   const unsigned int shnum = this->shnum();
-  bool is_gc_pass_one = ((parameters->options().gc_sections()
-                         && !symtab->gc()->is_worklist_ready())
-                        || (parameters->options().icf_enabled()
-                            && !symtab->icf()->is_icf_ready()));
 
-  bool is_gc_pass_two = ((parameters->options().gc_sections()
-                         && symtab->gc()->is_worklist_ready())
-                        || (parameters->options().icf_enabled()
-                            && symtab->icf()->is_icf_ready()));
+  /* Should this function be called twice?  */
+  bool is_two_pass = (parameters->options().gc_sections()
+                     || parameters->options().icf_enabled()
+                     || layout->is_unique_segment_for_sections_specified());
 
-  bool is_gc_or_icf = (parameters->options().gc_sections()
-                      || parameters->options().icf_enabled());
+  /* Only one of is_pass_one and is_pass_two is true.  Both are false when
+     a two-pass approach is not needed.  */
+  bool is_pass_one = false;
+  bool is_pass_two = false;
 
-  // Both is_gc_pass_one and is_gc_pass_two should not be true.
-  gold_assert(!(is_gc_pass_one  && is_gc_pass_two));
+  Symbols_data* gc_sd = NULL;
 
+  /* Check if do_layout needs to be two-pass.  If so, find out which pass
+     should happen.  In the first pass, the data in sd is saved to be used
+     later in the second pass.  */
+  if (is_two_pass)
+    {
+      gc_sd = this->get_symbols_data();
+      if (gc_sd == NULL)
+       {
+         gold_assert(sd != NULL);
+         is_pass_one = true;
+       }
+      else
+       {
+         if (parameters->options().gc_sections())
+           gold_assert(symtab->gc()->is_worklist_ready());
+         if (parameters->options().icf_enabled())
+           gold_assert(symtab->icf()->is_icf_ready()); 
+         is_pass_two = true;
+       }
+    }
+    
   if (shnum == 0)
     return;
-  Symbols_data* gc_sd = NULL;
-  if (is_gc_pass_one)
+
+  if (is_pass_one)
     {
       // During garbage collection save the symbols data to use it when
       // re-entering this function.
@@ -1265,10 +1321,6 @@ Sized_relobj_file<size, big_endian>::do_layout(Symbol_table* symtab,
       this->copy_symbols_data(gc_sd, sd, This::shdr_size * shnum);
       this->set_symbols_data(gc_sd);
     }
-  else if (is_gc_pass_two)
-    {
-      gc_sd = this->get_symbols_data();
-    }
 
   const unsigned char* section_headers_data = NULL;
   section_size_type section_names_size;
@@ -1277,7 +1329,7 @@ Sized_relobj_file<size, big_endian>::do_layout(Symbol_table* symtab,
   const unsigned char* symbol_names_data = NULL;
   section_size_type symbol_names_size;
 
-  if (is_gc_or_icf)
+  if (is_two_pass)
     {
       section_headers_data = gc_sd->section_headers_data;
       section_names_size = gc_sd->section_names_size;
@@ -1303,9 +1355,9 @@ Sized_relobj_file<size, big_endian>::do_layout(Symbol_table* symtab,
   const unsigned char* pshdrs;
 
   // Get the section names.
-  const unsigned char* pnamesu = (is_gc_or_icf)
-                                ? gc_sd->section_names_data
-                                : sd->section_names->data();
+  const unsigned char* pnamesu = (is_two_pass
+                                 ? gc_sd->section_names_data
+                                 : sd->section_names->data());
 
   const char* pnames = reinterpret_cast<const char*>(pnamesu);
 
@@ -1355,7 +1407,7 @@ Sized_relobj_file<size, big_endian>::do_layout(Symbol_table* symtab,
   Output_sections& out_sections(this->output_sections());
   std::vector<Address>& out_section_offsets(this->section_offsets());
 
-  if (!is_gc_pass_two)
+  if (!is_pass_two)
     {
       out_sections.resize(shnum);
       out_section_offsets.resize(shnum);
@@ -1365,7 +1417,7 @@ Sized_relobj_file<size, big_endian>::do_layout(Symbol_table* symtab,
   // do here.
   if (this->input_file()->just_symbols())
     {
-      if (!is_gc_pass_two)
+      if (!is_pass_two)
        {
          delete sd->section_headers;
          sd->section_headers = NULL;
@@ -1379,6 +1431,7 @@ Sized_relobj_file<size, big_endian>::do_layout(Symbol_table* symtab,
     {
       parameters->options().plugins()->add_deferred_layout_object(this);
       this->deferred_layout_.reserve(num_sections_to_defer);
+      this->is_deferred_layout_ = true;
     }
 
   // Whether we've seen a .note.GNU-stack section.
@@ -1417,7 +1470,7 @@ Sized_relobj_file<size, big_endian>::do_layout(Symbol_table* symtab,
 
       const char* name = pnames + shdr.get_sh_name();
 
-      if (!is_gc_pass_two)
+      if (!is_pass_two)
        {
          if (this->handle_gnu_warning_section(name, i, symtab))
            {
@@ -1491,9 +1544,10 @@ Sized_relobj_file<size, big_endian>::do_layout(Symbol_table* symtab,
            }
        }
 
-      if (is_gc_pass_one && parameters->options().gc_sections())
+      if (is_pass_one && parameters->options().gc_sections())
        {
          if (this->is_section_name_included(name)
+             || layout->keep_input_section (this, name)
              || shdr.get_sh_type() == elfcpp::SHT_INIT_ARRAY
              || shdr.get_sh_type() == elfcpp::SHT_FINI_ARRAY)
            {
@@ -1536,12 +1590,15 @@ Sized_relobj_file<size, big_endian>::do_layout(Symbol_table* symtab,
          && strcmp(name, ".eh_frame") == 0
          && this->check_eh_frame_flags(&shdr))
        {
-         if (is_gc_pass_one)
+         if (is_pass_one)
            {
-             out_sections[i] = reinterpret_cast<Output_section*>(1);
+             if (this->is_deferred_layout())
+               out_sections[i] = reinterpret_cast<Output_section*>(2);
+             else
+               out_sections[i] = reinterpret_cast<Output_section*>(1);
              out_section_offsets[i] = invalid_address;
            }
-         else if (should_defer_layout)
+         else if (this->is_deferred_layout())
            this->deferred_layout_.push_back(Deferred_layout(i, name,
                                                             pshdrs,
                                                             reloc_shndx[i],
@@ -1551,7 +1608,7 @@ Sized_relobj_file<size, big_endian>::do_layout(Symbol_table* symtab,
          continue;
        }
 
-      if (is_gc_pass_two && parameters->options().gc_sections())
+      if (is_pass_two && parameters->options().gc_sections())
        {
          // This is executed during the second pass of garbage
          // collection. do_layout has been called before and some
@@ -1576,7 +1633,7 @@ Sized_relobj_file<size, big_endian>::do_layout(Symbol_table* symtab,
              }
        }
 
-      if (is_gc_pass_two && parameters->options().icf_enabled())
+      if (is_pass_two && parameters->options().icf_enabled())
        {
          if (out_sections[i] == NULL)
            {
@@ -1592,7 +1649,7 @@ Sized_relobj_file<size, big_endian>::do_layout(Symbol_table* symtab,
                                symtab->icf()->get_folded_section(this, i);
                    Relobj* folded_obj =
                                reinterpret_cast<Relobj*>(folded.first);
-                   gold_info(_("%s: ICF folding section '%s' in file '%s'"
+                   gold_info(_("%s: ICF folding section '%s' in file '%s' "
                                "into '%s' in file '%s'"),
                              program_name, this->section_name(i).c_str(),
                              this->name().c_str(),
@@ -1606,11 +1663,12 @@ Sized_relobj_file<size, big_endian>::do_layout(Symbol_table* symtab,
        }
 
       // Defer layout here if input files are claimed by plugins.  When gc
-      // is turned on this function is called twice.  For the second call
-      // should_defer_layout should be false.
-      if (should_defer_layout && (shdr.get_sh_flags() & elfcpp::SHF_ALLOC))
+      // is turned on this function is called twice; we only want to do this
+      // on the first pass.
+      if (!is_pass_two
+          && this->is_deferred_layout()
+          && (shdr.get_sh_flags() & elfcpp::SHF_ALLOC))
        {
-         gold_assert(!is_gc_pass_two);
          this->deferred_layout_.push_back(Deferred_layout(i, name,
                                                           pshdrs,
                                                           reloc_shndx[i],
@@ -1625,11 +1683,11 @@ Sized_relobj_file<size, big_endian>::do_layout(Symbol_table* symtab,
       // During gc_pass_two if a section that was previously deferred is
       // found, do not layout the section as layout_deferred_sections will
       // do it later from gold.cc.
-      if (is_gc_pass_two
+      if (is_pass_two
          && (out_sections[i] == reinterpret_cast<Output_section*>(2)))
        continue;
 
-      if (is_gc_pass_one)
+      if (is_pass_one)
        {
          // This is during garbage collection. The out_sections are
          // assigned in the second call to this function.
@@ -1660,16 +1718,38 @@ Sized_relobj_file<size, big_endian>::do_layout(Symbol_table* symtab,
        }
     }
 
-  if (!is_gc_pass_two)
+  if (!is_pass_two)
     layout->layout_gnu_stack(seen_gnu_stack, gnu_stack_flags, this);
 
+  // Handle the .eh_frame sections after the other sections.
+  gold_assert(!is_pass_one || eh_frame_sections.empty());
+  for (std::vector<unsigned int>::const_iterator p = eh_frame_sections.begin();
+       p != eh_frame_sections.end();
+       ++p)
+    {
+      unsigned int i = *p;
+      const unsigned char* pshdr;
+      pshdr = section_headers_data + i * This::shdr_size;
+      typename This::Shdr shdr(pshdr);
+
+      this->layout_eh_frame_section(layout,
+                                   symbols_data,
+                                   symbols_size,
+                                   symbol_names_data,
+                                   symbol_names_size,
+                                   i,
+                                   shdr,
+                                   reloc_shndx[i],
+                                   reloc_type[i]);
+    }
+
   // When doing a relocatable link handle the reloc sections at the
   // end.  Garbage collection  and Identical Code Folding is not
   // turned on for relocatable code.
   if (emit_relocs)
     this->size_relocatable_relocs();
 
-  gold_assert(!(is_gc_or_icf) || reloc_sections.empty());
+  gold_assert(!is_two_pass || reloc_sections.empty());
 
   for (std::vector<unsigned int>::const_iterator p = reloc_sections.begin();
        p != reloc_sections.end();
@@ -1690,6 +1770,8 @@ Sized_relobj_file<size, big_endian>::do_layout(Symbol_table* symtab,
       Output_section* data_section = out_sections[data_shndx];
       if (data_section == reinterpret_cast<Output_section*>(2))
        {
+         if (is_pass_two)
+           continue;
          // The layout for the data section was deferred, so we need
          // to defer the relocation section, too.
          const char* name = pnames + shdr.get_sh_name();
@@ -1715,31 +1797,9 @@ Sized_relobj_file<size, big_endian>::do_layout(Symbol_table* symtab,
       out_section_offsets[i] = invalid_address;
     }
 
-  // Handle the .eh_frame sections at the end.
-  gold_assert(!is_gc_pass_one || eh_frame_sections.empty());
-  for (std::vector<unsigned int>::const_iterator p = eh_frame_sections.begin();
-       p != eh_frame_sections.end();
-       ++p)
-    {
-      unsigned int i = *p;
-      const unsigned char* pshdr;
-      pshdr = section_headers_data + i * This::shdr_size;
-      typename This::Shdr shdr(pshdr);
-
-      this->layout_eh_frame_section(layout,
-                                   symbols_data,
-                                   symbols_size,
-                                   symbol_names_data,
-                                   symbol_names_size,
-                                   i,
-                                   shdr,
-                                   reloc_shndx[i],
-                                   reloc_type[i]);
-    }
-
   // When building a .gdb_index section, scan the .debug_info and
   // .debug_types sections.
-  gold_assert(!is_gc_pass_one
+  gold_assert(!is_pass_one
              || (debug_info_sections.empty() && debug_types_sections.empty()));
   for (std::vector<unsigned int>::const_iterator p
           = debug_info_sections.begin();
@@ -1760,7 +1820,7 @@ Sized_relobj_file<size, big_endian>::do_layout(Symbol_table* symtab,
                               i, reloc_shndx[i], reloc_type[i]);
     }
 
-  if (is_gc_pass_two)
+  if (is_pass_two)
     {
       delete[] gc_sd->section_headers_data;
       delete[] gc_sd->section_names_data;
@@ -1791,22 +1851,24 @@ Sized_relobj_file<size, big_endian>::do_layout_deferred_sections(Layout* layout)
        ++deferred)
     {
       typename This::Shdr shdr(deferred->shdr_data_);
-      // If the section is not included, it is because the garbage collector
-      // decided it is not needed.  Avoid reverting that decision.
-      if (!this->is_section_included(deferred->shndx_))
-       continue;
 
-      if (parameters->options().relocatable()
-         || deferred->name_ != ".eh_frame"
-         || !this->check_eh_frame_flags(&shdr))
-       this->layout_section(layout, deferred->shndx_, deferred->name_.c_str(),
-                            shdr, deferred->reloc_shndx_,
-                            deferred->reloc_type_);
-      else
+      if (!parameters->options().relocatable()
+         && deferred->name_ == ".eh_frame"
+         && this->check_eh_frame_flags(&shdr))
        {
+         // Checking is_section_included is not reliable for
+         // .eh_frame sections, because they do not have an output
+         // section.  This is not a problem normally because we call
+         // layout_eh_frame_section unconditionally, but when
+         // deferring sections that is not true.  We don't want to
+         // keep all .eh_frame sections because that will cause us to
+         // keep all sections that they refer to, which is the wrong
+         // way around.  Instead, the eh_frame code will discard
+         // .eh_frame sections that refer to discarded sections.
+
          // Reading the symbols again here may be slow.
          Read_symbols_data sd;
-         this->read_symbols(&sd);
+         this->base_read_symbols(&sd);
          this->layout_eh_frame_section(layout,
                                        sd.symbols->data(),
                                        sd.symbols_size,
@@ -1816,7 +1878,17 @@ Sized_relobj_file<size, big_endian>::do_layout_deferred_sections(Layout* layout)
                                        shdr,
                                        deferred->reloc_shndx_,
                                        deferred->reloc_type_);
+         continue;
        }
+
+      // If the section is not included, it is because the garbage collector
+      // decided it is not needed.  Avoid reverting that decision.
+      if (!this->is_section_included(deferred->shndx_))
+       continue;
+
+      this->layout_section(layout, deferred->shndx_, deferred->name_.c_str(),
+                          shdr, deferred->reloc_shndx_,
+                          deferred->reloc_type_);
     }
 
   this->deferred_layout_.clear();
@@ -2090,7 +2162,8 @@ Sized_relobj_file<size, big_endian>::do_count_local_symbols(Stringpool* pool,
          continue;
        }
 
-      if (sym.get_st_type() == elfcpp::STT_SECTION)
+      if (sym.get_st_type() == elfcpp::STT_SECTION
+         || !this->adjust_local_symbol(&lv))
        {
          lv.set_no_output_symtab_entry();
          gold_assert(!lv.needs_output_dynsym_entry());
@@ -2294,7 +2367,9 @@ Sized_relobj_file<size, big_endian>::compute_final_local_value_internal(
              lv_out->set_merged_symbol_value(msv);
            }
        }
-      else if (lv_in->is_tls_symbol())
+      else if (lv_in->is_tls_symbol()
+               || (lv_in->is_section_symbol()
+                   && (os->flags() & elfcpp::SHF_TLS)))
        lv_out->set_output_value(os->tls_offset()
                                 + secoffset
                                 + lv_in->input_value());
@@ -2650,6 +2725,7 @@ Sized_relobj_file<size, big_endian>::get_symbol_location_info(
          && (static_cast<off_t>(sym.get_st_value() + sym.get_st_size())
              > offset))
        {
+         info->enclosing_symbol_type = sym.get_st_type();
          if (sym.get_st_name() > names_size)
            info->enclosing_symbol_name = "(invalid)";
          else
@@ -2959,12 +3035,10 @@ Relocate_info<size, big_endian>::location(size_t, off_t offset) const
          ret += ":";
          ret += info.source_file;
        }
-      size_t len = info.enclosing_symbol_name.length() + 100;
-      char* buf = new char[len];
-      snprintf(buf, len, _(":function %s"),
-              info.enclosing_symbol_name.c_str());
-      ret += buf;
-      delete[] buf;
+      ret += ":";
+      if (info.enclosing_symbol_type == elfcpp::STT_FUNC)
+       ret += _("function ");
+      ret += info.enclosing_symbol_name;
       return ret;
     }
 
@@ -3140,6 +3214,10 @@ template
 void
 Object::read_section_data<32, false>(elfcpp::Elf_file<32, false, Object>*,
                                     Read_symbols_data*);
+template
+const unsigned char*
+Object::find_shdr<32,false>(const unsigned char*, const char*, const char*,
+                           section_size_type, const unsigned char*) const;
 #endif
 
 #ifdef HAVE_TARGET_32_BIG
@@ -3147,6 +3225,10 @@ template
 void
 Object::read_section_data<32, true>(elfcpp::Elf_file<32, true, Object>*,
                                    Read_symbols_data*);
+template
+const unsigned char*
+Object::find_shdr<32,true>(const unsigned char*, const char*, const char*,
+                          section_size_type, const unsigned char*) const;
 #endif
 
 #ifdef HAVE_TARGET_64_LITTLE
@@ -3154,6 +3236,10 @@ template
 void
 Object::read_section_data<64, false>(elfcpp::Elf_file<64, false, Object>*,
                                     Read_symbols_data*);
+template
+const unsigned char*
+Object::find_shdr<64,false>(const unsigned char*, const char*, const char*,
+                           section_size_type, const unsigned char*) const;
 #endif
 
 #ifdef HAVE_TARGET_64_BIG
@@ -3161,25 +3247,41 @@ template
 void
 Object::read_section_data<64, true>(elfcpp::Elf_file<64, true, Object>*,
                                    Read_symbols_data*);
+template
+const unsigned char*
+Object::find_shdr<64,true>(const unsigned char*, const char*, const char*,
+                          section_size_type, const unsigned char*) const;
 #endif
 
 #ifdef HAVE_TARGET_32_LITTLE
 template
+class Sized_relobj<32, false>;
+
+template
 class Sized_relobj_file<32, false>;
 #endif
 
 #ifdef HAVE_TARGET_32_BIG
 template
+class Sized_relobj<32, true>;
+
+template
 class Sized_relobj_file<32, true>;
 #endif
 
 #ifdef HAVE_TARGET_64_LITTLE
 template
+class Sized_relobj<64, false>;
+
+template
 class Sized_relobj_file<64, false>;
 #endif
 
 #ifdef HAVE_TARGET_64_BIG
 template
+class Sized_relobj<64, true>;
+
+template
 class Sized_relobj_file<64, true>;
 #endif