remote.c/all-stop: Implement TARGET_WAITKIND_NO_RESUMED and TARGET_WNOHANG
[binutils-gdb.git] / gold / sparc.cc
index 04a88bf21bea5939ce1774f50aacda0cf844b3ee..d34585a9b6e5df83a562841304a727e07d716924 100644 (file)
@@ -1,6 +1,6 @@
 // sparc.cc -- sparc target support for gold.
 
-// Copyright 2008, 2009, 2010, 2011, 2012 Free Software Foundation, Inc.
+// Copyright (C) 2008-2015 Free Software Foundation, Inc.
 // Written by David S. Miller <davem@davemloft.net>.
 
 // This file is part of gold.
@@ -59,7 +59,7 @@ class Target_sparc : public Sized_target<size, big_endian>
   Target_sparc()
     : Sized_target<size, big_endian>(&sparc_info),
       got_(NULL), plt_(NULL), rela_dyn_(NULL), rela_ifunc_(NULL),
-      copy_relocs_(elfcpp::R_SPARC_COPY), dynbss_(NULL),
+      copy_relocs_(elfcpp::R_SPARC_COPY),
       got_mod_index_offset_(-1U), tls_get_addr_sym_(NULL),
       elf_machine_(sparc_info.machine_code), elf_flags_(0),
       elf_flags_set_(false)
@@ -138,7 +138,8 @@ class Target_sparc : public Sized_target<size, big_endian>
                  const unsigned char* prelocs,
                  size_t reloc_count,
                  Output_section* output_section,
-                 off_t offset_in_output_section,
+                 typename elfcpp::Elf_types<size>::Elf_Off
+                    offset_in_output_section,
                  const Relocatable_relocs*,
                  unsigned char* view,
                  typename elfcpp::Elf_types<size>::Elf_Addr view_address,
@@ -216,7 +217,7 @@ class Target_sparc : public Sized_target<size, big_endian>
                     const elfcpp::Ehdr<size, big_endian>& ehdr);
 
   void
-  do_adjust_elf_header(unsigned char* view, int len) const;
+  do_adjust_elf_header(unsigned char* view, int len);
 
  private:
 
@@ -237,7 +238,8 @@ class Target_sparc : public Sized_target<size, big_endian>
          unsigned int data_shndx,
          Output_section* output_section,
          const elfcpp::Rela<size, big_endian>& reloc, unsigned int r_type,
-         const elfcpp::Sym<size, big_endian>& lsym);
+         const elfcpp::Sym<size, big_endian>& lsym,
+         bool is_discarded);
 
     inline void
     global(Symbol_table* symtab, Layout* layout, Target_sparc* target,
@@ -444,8 +446,6 @@ class Target_sparc : public Sized_target<size, big_endian>
   Reloc_section* rela_ifunc_;
   // Relocs saved to avoid a COPY reloc.
   Copy_relocs<elfcpp::SHT_RELA, size, big_endian> copy_relocs_;
-  // Space for variables copied with a COPY reloc.
-  Output_data_space* dynbss_;
   // Offset of the GOT entry for the TLS module index;
   unsigned int got_mod_index_offset_;
   // Cached pointer to __tls_get_addr symbol
@@ -481,7 +481,8 @@ Target::Target_info Target_sparc<32, true>::sparc_info =
   0,                   // small_common_section_flags
   0,                   // large_common_section_flags
   NULL,                        // attributes_section
-  NULL                 // attributes_vendor
+  NULL,                        // attributes_vendor
+  "_start"             // entry_symbol_name
 };
 
 template<>
@@ -507,7 +508,8 @@ Target::Target_info Target_sparc<64, true>::sparc_info =
   0,                   // small_common_section_flags
   0,                   // large_common_section_flags
   NULL,                        // attributes_section
-  NULL                 // attributes_vendor
+  NULL,                        // attributes_vendor
+  "_start"             // entry_symbol_name
 };
 
 // We have to take care here, even when operating in little-endian
@@ -1618,7 +1620,7 @@ Output_data_plt_sparc<size, big_endian>::address_for_global(const Symbol* gsym)
   if (gsym->type() == elfcpp::STT_GNU_IFUNC
       && gsym->can_use_relative_reloc(false))
     offset = plt_index_to_offset(this->count_ + 4);
-  return this->address() + offset;
+  return this->address() + offset + gsym->plt_offset();
 }
 
 // Return the PLT address to use for a local symbol.  These are always
@@ -1627,10 +1629,12 @@ Output_data_plt_sparc<size, big_endian>::address_for_global(const Symbol* gsym)
 template<int size, bool big_endian>
 uint64_t
 Output_data_plt_sparc<size, big_endian>::address_for_local(
-       const Relobj*,
-       unsigned int)
+       const Relobj* object,
+       unsigned int r_sym)
 {
-  return this->address() + plt_index_to_offset(this->count_ + 4);
+  return (this->address()
+         + plt_index_to_offset(this->count_ + 4)
+         + object->local_plt_offset(r_sym));
 }
 
 static const unsigned int sparc_nop = 0x01000000;
@@ -2240,8 +2244,12 @@ Target_sparc<size, big_endian>::Scan::local(
                        Output_section* output_section,
                        const elfcpp::Rela<size, big_endian>& reloc,
                        unsigned int r_type,
-                       const elfcpp::Sym<size, big_endian>& lsym)
+                       const elfcpp::Sym<size, big_endian>& lsym,
+                       bool is_discarded)
 {
+  if (is_discarded)
+    return;
+
   bool is_ifunc = lsym.get_st_type() == elfcpp::STT_GNU_IFUNC;
   unsigned int orig_r_type = r_type;
   r_type &= 0xff;
@@ -2626,7 +2634,8 @@ Target_sparc<size, big_endian>::Scan::global(
        // Make a dynamic relocation if necessary.
        if (gsym->needs_dynamic_reloc(Scan::get_reference_flags(r_type)))
          {
-           if (gsym->may_need_copy_reloc())
+           if (parameters->options().output_is_executable()
+               && gsym->may_need_copy_reloc())
              {
                target->copy_reloc(symtab, layout, object,
                                   data_shndx, output_section, gsym,
@@ -2715,7 +2724,8 @@ Target_sparc<size, big_endian>::Scan::global(
                break;
              }
 
-           if (gsym->may_need_copy_reloc())
+           if (!parameters->options().output_is_position_independent()
+               && gsym->may_need_copy_reloc())
              {
                target->copy_reloc(symtab, layout, object,
                                   data_shndx, output_section, gsym, reloc);
@@ -3181,6 +3191,10 @@ Target_sparc<size, big_endian>::Relocate::relocate(
          return false;
        }
     }
+
+  if (view == NULL)
+    return true;
+
   if (this->reloc_adjust_addr_ == view)
     view -= 4;
 
@@ -3194,7 +3208,7 @@ Target_sparc<size, big_endian>::Relocate::relocate(
     {
       elfcpp::Elf_Xword value;
 
-      value = target->plt_address_for_global(gsym) + gsym->plt_offset();
+      value = target->plt_address_for_global(gsym);
 
       symval.set_output_value(value);
 
@@ -3205,8 +3219,7 @@ Target_sparc<size, big_endian>::Relocate::relocate(
       unsigned int r_sym = elfcpp::elf_r_sym<size>(rela.get_r_info());
       if (object->local_has_plt_offset(r_sym))
        {
-         symval.set_output_value(target->plt_address_for_local(object, r_sym)
-                                 + object->local_plt_offset(r_sym));
+         symval.set_output_value(target->plt_address_for_local(object, r_sym));
          psymval = &symval;
        }
     }
@@ -4132,7 +4145,7 @@ Target_sparc<size, big_endian>::relocate_section(
   gold_assert(sh_type == elfcpp::SHT_RELA);
 
   gold::relocate_section<size, big_endian, Sparc, elfcpp::SHT_RELA,
-    Sparc_relocate>(
+                        Sparc_relocate, gold::Default_comdat_behavior>(
     relinfo,
     this,
     prelocs,
@@ -4207,7 +4220,7 @@ Target_sparc<size, big_endian>::relocate_relocs(
     const unsigned char* prelocs,
     size_t reloc_count,
     Output_section* output_section,
-    off_t offset_in_output_section,
+    typename elfcpp::Elf_types<size>::Elf_Off offset_in_output_section,
     const Relocatable_relocs* rr,
     unsigned char* view,
     typename elfcpp::Elf_types<size>::Elf_Addr view_address,
@@ -4328,7 +4341,7 @@ template<int size, bool big_endian>
 void
 Target_sparc<size, big_endian>::do_adjust_elf_header(
     unsigned char* view,
-    int len) const
+    int len)
 {
   elfcpp::Ehdr_write<size, big_endian> oehdr(view);