public inbox for binutils@sourceware.org
 help / color / mirror / Atom feed
* [gold patch] Incremental 17/22: COPY relocations
@ 2011-04-26 23:57 Cary Coutant
  2011-06-08  0:31 ` Ian Lance Taylor
  0 siblings, 1 reply; 3+ messages in thread
From: Cary Coutant @ 2011-04-26 23:57 UTC (permalink / raw)
  To: Ian Lance Taylor, Binutils

[-- Attachment #1: Type: text/plain, Size: 2176 bytes --]

This patch adds incremental support for COPY relocations. In the
.gnu_incremental_inputs section, I used another bit to flag shared
library symbols that were targets of a COPY relocation. When
processing an unchanged library, do_add_symbols checks the flag and
regenerates the COPY relocation.

(I split a couple of patches and added a couple, so the total patch
count is now up to 22.)

-cary


2011-04-26 Cary Coutant  <ccoutant@google.com>

	* copy-relocs.cc (Copy_relocs::copy_reloc): Call make_copy_reloc
	instead of emit_copy_reloc.
	(Copy_relocs::emit_copy_reloc): Refactor.
	(Copy_relocs::make_copy_reloc): New function.
	(Copy_relocs::add_copy_reloc): Remove.
	* copy-relocs.h (Copy_relocs::emit_copy_reloc): Move to public
	section.
	(Copy_relocs::make_copy_reloc): New function.
	(Copy_relocs::add_copy_reloc): Remove.
	* gold.cc (queue_middle_tasks): Emit old COPY relocations from
	unchanged input files.
	* incremental-dump.cc (dump_incremental_inputs): Print "COPY" flag.
	* incremental.cc (Sized_incremental_binary::do_reserve_layout):
	Reserve BSS space for COPY relocations.
	(Sized_incremental_binary::do_emit_copy_relocs): New function.
	(Output_section_incremental_inputs::write_info_blocks): Record
	whether a symbol is copied from a shared object.
	(Sized_incr_dynobj::do_add_symbols): Record COPY relocations.
	* incremental.h
	(Incremental_input_entry_reader::get_output_symbol_index): Add
	is_copy parameter.
	(Incremental_binary::emit_copy_relocs): New function.
	(Incremental_binary::do_emit_copy_relocs): New function.
	(Sized_incremental_binary::Sized_incremental_binary): Initialize
	new data member.
	(Sized_incremental_binary::add_copy_reloc): New function.
	(Sized_incremental_binary::do_emit_copy_relocs): New function.
	(Sized_incremental_binary::Copy_reloc): New struct.
	(Sized_incremental_binary::Copy_relocs): New typedef.
	(Sized_incremental_binary::copy_relocs_): New data member.
	* symtab.cc (Symbol_table::add_from_incrobj): Change return type.
	* symtab.h (Symbol_table::add_from_incrobj): Change return type.
	* target.h (Sized_target::emit_copy_reloc): New function.
	* x86_64.cc (Target_x86_64::emit_copy_reloc): New function.

[-- Attachment #2: incr-patch-17.txt --]
[-- Type: text/plain, Size: 20836 bytes --]

Add support for COPY relocations.


2011-04-26 Cary Coutant  <ccoutant@google.com>

	* copy-relocs.cc (Copy_relocs::copy_reloc): Call make_copy_reloc
	instead of emit_copy_reloc.
	(Copy_relocs::emit_copy_reloc): Refactor.
	(Copy_relocs::make_copy_reloc): New function.
	(Copy_relocs::add_copy_reloc): Remove.
	* copy-relocs.h (Copy_relocs::emit_copy_reloc): Move to public
	section.
	(Copy_relocs::make_copy_reloc): New function.
	(Copy_relocs::add_copy_reloc): Remove.
	* gold.cc (queue_middle_tasks): Emit old COPY relocations from
	unchanged input files.
	* incremental-dump.cc (dump_incremental_inputs): Print "COPY" flag.
	* incremental.cc (Sized_incremental_binary::do_reserve_layout):
	Reserve BSS space for COPY relocations.
	(Sized_incremental_binary::do_emit_copy_relocs): New function.
	(Output_section_incremental_inputs::write_info_blocks): Record
	whether a symbol is copied from a shared object.
	(Sized_incr_dynobj::do_add_symbols): Record COPY relocations.
	* incremental.h
	(Incremental_input_entry_reader::get_output_symbol_index): Add
	is_copy parameter.
	(Incremental_binary::emit_copy_relocs): New function.
	(Incremental_binary::do_emit_copy_relocs): New function.
	(Sized_incremental_binary::Sized_incremental_binary): Initialize
	new data member.
	(Sized_incremental_binary::add_copy_reloc): New function.
	(Sized_incremental_binary::do_emit_copy_relocs): New function.
	(Sized_incremental_binary::Copy_reloc): New struct.
	(Sized_incremental_binary::Copy_relocs): New typedef.
	(Sized_incremental_binary::copy_relocs_): New data member.
	* symtab.cc (Symbol_table::add_from_incrobj): Change return type.
	* symtab.h (Symbol_table::add_from_incrobj): Change return type.
	* target.h (Sized_target::emit_copy_reloc): New function.
	* x86_64.cc (Target_x86_64::emit_copy_reloc): New function.


diff --git a/gold/copy-relocs.cc b/gold/copy-relocs.cc
index 4931aa0..b71dc87 100644
--- a/gold/copy-relocs.cc
+++ b/gold/copy-relocs.cc
@@ -65,7 +65,7 @@ Copy_relocs<sh_type, size, big_endian>::copy_reloc(
     Output_data_reloc<sh_type, true, size, big_endian>* reloc_section)
 {
   if (this->need_copy_reloc(sym, object, shndx))
-    this->emit_copy_reloc(symtab, layout, sym, reloc_section);
+    this->make_copy_reloc(symtab, layout, sym, reloc_section);
   else
     {
       // We may not need a COPY relocation.  Save this relocation to
@@ -106,6 +106,24 @@ template<int sh_type, int size, bool big_endian>
 void
 Copy_relocs<sh_type, size, big_endian>::emit_copy_reloc(
     Symbol_table* symtab,
+    Sized_symbol<size>* sym,
+    Output_data* posd,
+    off_t offset,
+    Output_data_reloc<sh_type, true, size, big_endian>* reloc_section)
+{
+  // Define the symbol as being copied.
+  symtab->define_with_copy_reloc(sym, posd, offset);
+
+  // Add the COPY relocation to the dynamic reloc section.
+  reloc_section->add_global(sym, this->copy_reloc_type_, posd, offset, 0);
+}
+
+// Make a COPY relocation for SYM and emit it.
+
+template<int sh_type, int size, bool big_endian>
+void
+Copy_relocs<sh_type, size, big_endian>::make_copy_reloc(
+    Symbol_table* symtab,
     Layout* layout,
     Sized_symbol<size>* sym,
     Output_data_reloc<sh_type, true, size, big_endian>* reloc_section)
@@ -164,24 +182,7 @@ Copy_relocs<sh_type, size, big_endian>::emit_copy_reloc(
   section_size_type offset = dynbss_size;
   dynbss->set_current_data_size(dynbss_size + symsize);
 
-  // Define the symbol as being copied.
-  symtab->define_with_copy_reloc(sym, dynbss, offset);
-
-  // Add the COPY relocation to the dynamic reloc section.
-  this->add_copy_reloc(sym, offset, reloc_section);
-}
-
-// Add a COPY relocation for SYM to RELOC_SECTION.
-
-template<int sh_type, int size, bool big_endian>
-void
-Copy_relocs<sh_type, size, big_endian>::add_copy_reloc(
-    Symbol* sym,
-    section_size_type offset,
-    Output_data_reloc<sh_type, true, size, big_endian>* reloc_section)
-{
-  reloc_section->add_global(sym, this->copy_reloc_type_, this->dynbss_,
-			    offset, 0);
+  this->emit_copy_reloc(symtab, sym, dynbss, offset, reloc_section);
 }
 
 // Save a relocation to possibly be emitted later.
diff --git a/gold/copy-relocs.h b/gold/copy-relocs.h
index 2fe6a24..908bcdb 100644
--- a/gold/copy-relocs.h
+++ b/gold/copy-relocs.h
@@ -81,6 +81,12 @@ class Copy_relocs
   void
   emit(Output_data_reloc<sh_type, true, size, big_endian>*);
 
+  // Emit a COPY reloc.
+  void
+  emit_copy_reloc(Symbol_table*, Sized_symbol<size>*,
+		  Output_data*, off_t,
+		  Output_data_reloc<sh_type, true, size, big_endian>*);
+
  private:
   typedef typename elfcpp::Elf_types<size>::Elf_Addr Address;
   typedef typename elfcpp::Elf_types<size>::Elf_Addr Addend;
@@ -126,16 +132,11 @@ class Copy_relocs
                   Sized_relobj<size, big_endian>* object,
 		  unsigned int shndx) const;
 
-  // Emit a COPY reloc.
+  // Make a new COPY reloc and emit it.
   void
-  emit_copy_reloc(Symbol_table*, Layout*, Sized_symbol<size>*,
+  make_copy_reloc(Symbol_table*, Layout*, Sized_symbol<size>*,
 		  Output_data_reloc<sh_type, true, size, big_endian>*);
 
-  // Add a COPY reloc to the dynamic reloc section.
-  void
-  add_copy_reloc(Symbol*, section_size_type,
-		 Output_data_reloc<sh_type, true, size, big_endian>*);
-
   // Save a reloc against SYM for possible emission later.
   void
   save(Symbol*, Sized_relobj<size, big_endian>*, unsigned int shndx,
diff --git a/gold/gold.cc b/gold/gold.cc
index 85b2907..283cab3 100644
--- a/gold/gold.cc
+++ b/gold/gold.cc
@@ -632,11 +632,13 @@ queue_middle_tasks(const General_options& options,
 	}
     }
 
-  // For incremental updates, record the existing GOT and PLT entries.
+  // For incremental updates, record the existing GOT and PLT entries,
+  // and the COPY relocations.
   if (parameters->incremental_update())
     {
       Incremental_binary* ibase = layout->incremental_base();
       ibase->process_got_plt(symtab, layout);
+      ibase->emit_copy_relocs(symtab);
     }
 
   if (is_debugging_enabled(DEBUG_SCRIPT))
diff --git a/gold/incremental-dump.cc b/gold/incremental-dump.cc
index 3e9bc0a..1147d07 100644
--- a/gold/incremental-dump.cc
+++ b/gold/incremental-dump.cc
@@ -293,8 +293,9 @@ dump_incremental_inputs(const char* argv0, const char* filename,
 	  for (unsigned int symndx = 0; symndx < nsyms; ++symndx)
 	    {
 	      bool is_def;
+	      bool is_copy;
 	      unsigned int output_symndx =
-		  input_file.get_output_symbol_index(symndx, &is_def);
+		  input_file.get_output_symbol_index(symndx, &is_def, &is_copy);
 	      sym_p = symtab_view.data() + output_symndx * sym_size;
 	      elfcpp::Sym<size, big_endian> sym(sym_p);
 	      const char* symname;
@@ -303,7 +304,7 @@ dump_incremental_inputs(const char* argv0, const char* filename,
 	      printf("    %6d  %6s  %8s  %8s  %8s  %8s  %-5s  %s\n",
 		     output_symndx,
 		     "", "", "", "", "",
-		     is_def ? "DEF" : "UNDEF",
+		     is_copy ? "COPY" : (is_def ? "DEF" : "UNDEF"),
 		     symname);
 	    }
 	}
diff --git a/gold/incremental.cc b/gold/incremental.cc
index 072a1fb..dca3431 100644
--- a/gold/incremental.cc
+++ b/gold/incremental.cc
@@ -22,6 +22,7 @@
 
 #include "gold.h"
 
+#include <set>
 #include <cstdarg>
 #include "libiberty.h"
 
@@ -518,11 +519,45 @@ void
 Sized_incremental_binary<size, big_endian>::do_reserve_layout(
     unsigned int input_file_index)
 {
+  const int sym_size = elfcpp::Elf_sizes<size>::sym_size;
+
   Input_entry_reader input_file =
       this->inputs_reader_.input_file(input_file_index);
 
   if (input_file.type() == INCREMENTAL_INPUT_SHARED_LIBRARY)
-    return;
+    {
+      // Reserve the BSS space used for COPY relocations.
+      unsigned int nsyms = input_file.get_global_symbol_count();
+      Incremental_binary::View symtab_view(NULL);
+      unsigned int symtab_count;
+      elfcpp::Elf_strtab strtab(NULL, 0);
+      this->get_symtab_view(&symtab_view, &symtab_count, &strtab);
+      for (unsigned int i = 0; i < nsyms; ++i)
+	{
+	  bool is_def;
+	  bool is_copy;
+          unsigned int output_symndx =
+	      input_file.get_output_symbol_index(i, &is_def, &is_copy);
+	  if (is_copy)
+	    {
+	      const unsigned char* sym_p = (symtab_view.data()
+					    + output_symndx * sym_size);
+	      elfcpp::Sym<size, big_endian> gsym(sym_p);
+	      unsigned int shndx = gsym.get_st_shndx();
+	      if (shndx < 1 || shndx >= this->section_map_.size())
+	        continue;
+	      Output_section* os = this->section_map_[shndx];
+	      off_t offset = gsym.get_st_value() - os->address();
+	      os->reserve(offset, gsym.get_st_size());
+	      gold_debug(DEBUG_INCREMENTAL,
+			 "Reserve for COPY reloc: %s, off %d, size %d",
+			 os->name(),
+			 static_cast<int>(offset),
+			 static_cast<int>(gsym.get_st_size()));
+	    }
+	}
+      return;
+    }
 
   unsigned int shnum = input_file.get_input_section_count();
   for (unsigned int i = 0; i < shnum; i++)
@@ -616,6 +651,26 @@ Sized_incremental_binary<size, big_endian>::do_process_got_plt(
     }
 }
 
+// Emit COPY relocations from the existing output file.
+
+template<int size, bool big_endian>
+void
+Sized_incremental_binary<size, big_endian>::do_emit_copy_relocs(
+    Symbol_table* symtab)
+{
+  Sized_target<size, big_endian>* target =
+      parameters->sized_target<size, big_endian>();
+
+  for (typename Copy_relocs::iterator p = this->copy_relocs_.begin();
+       p != this->copy_relocs_.end();
+       ++p)
+    {
+      if (!(*p).symbol->is_copied_from_dynobj())
+	target->emit_copy_reloc(symtab, (*p).symbol, (*p).output_section,
+				(*p).offset);
+    }
+}
+
 // Apply incremental relocations for symbols whose values have changed.
 
 template<int size, bool big_endian>
@@ -1537,7 +1592,9 @@ Output_section_incremental_inputs<size, big_endian>::write_info_blocks(
 			== (*p)->get_info_offset());
 	    Incremental_dynobj_entry* entry = (*p)->dynobj_entry();
 	    gold_assert(entry != NULL);
-	    const Object* obj = entry->object();
+	    Object* obj = entry->object();
+	    Dynobj* dynobj = obj->dynobj();
+	    gold_assert(dynobj != NULL);
 	    const Object::Symbols* syms = obj->get_global_symbols();
 
 	    // Write the soname string table index.
@@ -1566,7 +1623,10 @@ Output_section_incremental_inputs<size, big_endian>::write_info_blocks(
 		if (sym->source() == Symbol::FROM_OBJECT
 		    && sym->object() == obj
 		    && sym->is_defined())
-		  def_flag = 1U << 31;
+		  def_flag = 2U << 30;
+		else if (sym->is_copied_from_dynobj()
+			 && this->symtab_->get_copy_source(sym) == dynobj)
+		  def_flag = 3U << 30;
 		Swap32::writeval(pov, sym->symtab_index() | def_flag);
 		pov += 4;
 		++nsyms_out;
@@ -2474,19 +2534,26 @@ Sized_incr_dynobj<size, big_endian>::do_add_symbols(
   unsigned int isym_count = isymtab.symbol_count();
   unsigned int first_global = symtab_count - isym_count;
 
+  // We keep a set of symbols that we have generated COPY relocations
+  // for, indexed by the symbol value. We do not need more than one
+  // COPY relocation per address.
+  typedef typename std::set<Address> Copied_symbols;
+  Copied_symbols copied_symbols;
+
   const unsigned char* sym_p;
   for (unsigned int i = 0; i < nsyms; ++i)
     {
       bool is_def;
+      bool is_copy;
       unsigned int output_symndx =
-	  this->input_reader_.get_output_symbol_index(i, &is_def);
+	  this->input_reader_.get_output_symbol_index(i, &is_def, &is_copy);
       sym_p = symtab_view.data() + output_symndx * sym_size;
       elfcpp::Sym<size, big_endian> gsym(sym_p);
       const char* name;
       if (!strtab.get_c_string(gsym.get_st_name(), &name))
 	name = "";
 
-      typename elfcpp::Elf_types<size>::Elf_Addr v;
+      Address v;
       unsigned int shndx;
       elfcpp::STB st_bind = gsym.get_st_bind();
       elfcpp::STT st_type = gsym.get_st_type();
@@ -2516,10 +2583,24 @@ Sized_incr_dynobj<size, big_endian>::do_add_symbols(
       osym.put_st_other(gsym.get_st_other());
       osym.put_st_shndx(shndx);
 
-      this->symbols_[i] =
-	symtab->add_from_incrobj<size, big_endian>(this, name, NULL, &sym);
+      Sized_symbol<size>* res =
+	  symtab->add_from_incrobj<size, big_endian>(this, name, NULL, &sym);
+      this->symbols_[i] = res;
       this->ibase_->add_global_symbol(output_symndx - first_global,
 				      this->symbols_[i]);
+
+      if (is_copy)
+	{
+	  std::pair<typename Copied_symbols::iterator, bool> ins =
+	      copied_symbols.insert(v);
+	  if (ins.second)
+	    {
+	      unsigned int shndx = gsym.get_st_shndx();
+	      Output_section* os = this->ibase_->output_section(shndx);
+	      off_t offset = v - os->address();
+	      this->ibase_->add_copy_reloc(this->symbols_[i], os, offset);
+	    }
+	}
     }
 }
 
diff --git a/gold/incremental.h b/gold/incremental.h
index 998e69e..f5479ac 100644
--- a/gold/incremental.h
+++ b/gold/incremental.h
@@ -1012,17 +1012,19 @@ class Incremental_inputs_reader
 
     // Return the output symbol index for the Nth global symbol -- for shared
     // libraries only.  Sets *IS_DEF to TRUE if the symbol is defined in this
-    // input file.
+    // input file.  Sets *IS_COPY to TRUE if the symbol was copied from this
+    // input file with a COPY relocation.
     unsigned int
-    get_output_symbol_index(unsigned int n, bool* is_def)
+    get_output_symbol_index(unsigned int n, bool* is_def, bool* is_copy)
     {
       gold_assert(this->type() == INCREMENTAL_INPUT_SHARED_LIBRARY);
       const unsigned char* p = (this->inputs_->p_
 				+ this->info_offset_ + 8
 				+ n * 4);
       unsigned int output_symndx = Swap32::readval(p);
-      *is_def = (output_symndx & (1U << 31)) != 0;
-      return output_symndx & ((1U << 31) - 1);
+      *is_def = (output_symndx >> 31) == 1;
+      *is_copy = (output_symndx >> 30) == 3;
+      return output_symndx & ((1U << 30) - 1);
     }
 
    private:
@@ -1397,6 +1399,11 @@ class Incremental_binary
   process_got_plt(Symbol_table* symtab, Layout* layout)
   { this->do_process_got_plt(symtab, layout); }
 
+  // Emit COPY relocations from the existing output file.
+  void
+  emit_copy_relocs(Symbol_table* symtab)
+  { this->do_emit_copy_relocs(symtab); }
+
   // Apply incremental relocations for symbols whose values have changed.
   void
   apply_incremental_relocs(const Symbol_table* symtab, Layout* layout,
@@ -1479,6 +1486,10 @@ class Incremental_binary
   virtual void
   do_process_got_plt(Symbol_table* symtab, Layout* layout) = 0;
 
+  // Emit COPY relocations from the existing output file.
+  virtual void
+  do_emit_copy_relocs(Symbol_table* symtab) = 0;
+
   // Apply incremental relocations for symbols whose values have changed.
   virtual void
   do_apply_incremental_relocs(const Symbol_table*, Layout*, Output_file*) = 0;
@@ -1514,9 +1525,9 @@ class Sized_incremental_binary : public Incremental_binary
                            const elfcpp::Ehdr<size, big_endian>& ehdr,
                            Target* target)
     : Incremental_binary(output, target), elf_file_(this, ehdr),
-      input_objects_(), section_map_(), symbol_map_(), main_symtab_loc_(),
-      main_strtab_loc_(), has_incremental_info_(false), inputs_reader_(),
-      symtab_reader_(), relocs_reader_(), got_plt_reader_(),
+      input_objects_(), section_map_(), symbol_map_(), copy_relocs_(),
+      main_symtab_loc_(), main_strtab_loc_(), has_incremental_info_(false),
+      inputs_reader_(), symtab_reader_(), relocs_reader_(), got_plt_reader_(),
       input_entry_readers_()
   { this->setup_readers(); }
 
@@ -1558,6 +1569,11 @@ class Sized_incremental_binary : public Incremental_binary
   global_symbol(unsigned int symndx) const
   { return this->symbol_map_[symndx]; }
 
+  // Add a COPY relocation for a global symbol.
+  void
+  add_copy_reloc(Symbol* gsym, Output_section* os, off_t offset)
+  { this->copy_relocs_.push_back(Copy_reloc(gsym, os, offset)); }
+
   // Readers for the incremental info sections.
 
   const Incremental_inputs_reader<size, big_endian>&
@@ -1606,6 +1622,10 @@ class Sized_incremental_binary : public Incremental_binary
   virtual void
   do_process_got_plt(Symbol_table* symtab, Layout* layout);
 
+  // Emit COPY relocations from the existing output file.
+  virtual void
+  do_emit_copy_relocs(Symbol_table* symtab);
+
   // Apply incremental relocations for symbols whose values have changed.
   virtual void
   do_apply_incremental_relocs(const Symbol_table* symtab, Layout* layout,
@@ -1664,6 +1684,22 @@ class Sized_incremental_binary : public Incremental_binary
   }
 
  private:
+  // List of symbols that need COPY relocations.
+  struct Copy_reloc
+  {
+    Copy_reloc(Symbol* sym, Output_section* os, off_t off)
+      : symbol(sym), output_section(os), offset(off)
+    { }
+
+    // The global symbol to copy.
+    Symbol* symbol;
+    // The output section into which the symbol was copied.
+    Output_section* output_section;
+    // The offset within that output section.
+    off_t offset;
+  };
+  typedef std::vector<Copy_reloc> Copy_relocs;
+
   bool
   find_incremental_inputs_sections(unsigned int* p_inputs_shndx,
 				   unsigned int* p_symtab_shndx,
@@ -1687,6 +1723,9 @@ class Sized_incremental_binary : public Incremental_binary
   // Map global symbols from the input file to the symbol table.
   std::vector<Symbol*> symbol_map_;
 
+  // List of symbols that need COPY relocations.
+  Copy_relocs copy_relocs_;
+
   // Locations of the main symbol table and symbol string table.
   Location main_symtab_loc_;
   Location main_strtab_loc_;
diff --git a/gold/symtab.cc b/gold/symtab.cc
index 3880ce1..0421b66 100644
--- a/gold/symtab.cc
+++ b/gold/symtab.cc
@@ -1489,7 +1489,7 @@ Symbol_table::add_from_dynobj(
 // Add a symbol from a incremental object file.
 
 template<int size, bool big_endian>
-Symbol*
+Sized_symbol<size>*
 Symbol_table::add_from_incrobj(
     Object* obj,
     const char* name,
@@ -3453,7 +3453,7 @@ Symbol_table::add_from_dynobj<64, true>(
 
 #ifdef HAVE_TARGET_32_LITTLE
 template
-Symbol*
+Sized_symbol<32>*
 Symbol_table::add_from_incrobj(
     Object* obj,
     const char* name,
@@ -3463,7 +3463,7 @@ Symbol_table::add_from_incrobj(
 
 #ifdef HAVE_TARGET_32_BIG
 template
-Symbol*
+Sized_symbol<32>*
 Symbol_table::add_from_incrobj(
     Object* obj,
     const char* name,
@@ -3473,7 +3473,7 @@ Symbol_table::add_from_incrobj(
 
 #ifdef HAVE_TARGET_64_LITTLE
 template
-Symbol*
+Sized_symbol<64>*
 Symbol_table::add_from_incrobj(
     Object* obj,
     const char* name,
@@ -3483,7 +3483,7 @@ Symbol_table::add_from_incrobj(
 
 #ifdef HAVE_TARGET_64_BIG
 template
-Symbol*
+Sized_symbol<64>*
 Symbol_table::add_from_incrobj(
     Object* obj,
     const char* name,
diff --git a/gold/symtab.h b/gold/symtab.h
index 4196138..e8d8238 100644
--- a/gold/symtab.h
+++ b/gold/symtab.h
@@ -1341,7 +1341,7 @@ class Symbol_table
   // Add one external symbol from the incremental object OBJ to the symbol
   // table.  Returns a pointer to the resolved symbol in the symbol table.
   template<int size, bool big_endian>
-  Symbol*
+  Sized_symbol<size>*
   add_from_incrobj(Object* obj, const char* name,
 		   const char* ver, elfcpp::Sym<size, big_endian>* sym);
 
diff --git a/gold/target.h b/gold/target.h
index e675204..0731544 100644
--- a/gold/target.h
+++ b/gold/target.h
@@ -833,6 +833,13 @@ class Sized_target : public Target
 			    Symbol*)
   { gold_unreachable(); }
 
+  // Force a COPY relocation for a given symbol.
+  // A target needs to implement this to support incremental linking.
+
+  virtual void
+  emit_copy_reloc(Symbol_table*, Symbol*, Output_section*, off_t)
+  { gold_unreachable(); }
+
   // Apply an incremental relocation.
 
   virtual void
diff --git a/gold/x86_64.cc b/gold/x86_64.cc
index 1a54fb0..7294e23 100644
--- a/gold/x86_64.cc
+++ b/gold/x86_64.cc
@@ -405,10 +405,13 @@ class Target_x86_64 : public Target_freebsd<64, false>
 			   unsigned int got_type);
 
   // Register an existing PLT entry for a global symbol.
-  // A target needs to implement this to support incremental linking.
   void
   register_global_plt_entry(unsigned int plt_index, Symbol* gsym);
 
+  // Force a COPY relocation for a given symbol.
+  void
+  emit_copy_reloc(Symbol_table*, Symbol*, Output_section*, off_t);
+
   // Apply an incremental relocation.
   void
   apply_relocation(const Relocate_info<64, false>* relinfo,
@@ -1387,6 +1390,19 @@ Target_x86_64::register_global_plt_entry(unsigned int plt_index,
   this->plt_->add_relocation(gsym, got_offset);
 }
 
+// Force a COPY relocation for a given symbol.
+
+void
+Target_x86_64::emit_copy_reloc(
+    Symbol_table* symtab, Symbol* sym, Output_section* os, off_t offset)
+{
+  this->copy_relocs_.emit_copy_reloc(symtab,
+				     symtab->get_sized_symbol<64>(sym),
+				     os,
+				     offset,
+				     this->rela_dyn_section(NULL));
+}
+
 // Define the _TLS_MODULE_BASE_ symbol in the TLS segment.
 
 void

^ permalink raw reply	[flat|nested] 3+ messages in thread

* Re: [gold patch] Incremental 17/22: COPY relocations
  2011-04-26 23:57 [gold patch] Incremental 17/22: COPY relocations Cary Coutant
@ 2011-06-08  0:31 ` Ian Lance Taylor
  2011-06-08  3:54   ` Cary Coutant
  0 siblings, 1 reply; 3+ messages in thread
From: Ian Lance Taylor @ 2011-06-08  0:31 UTC (permalink / raw)
  To: Cary Coutant; +Cc: Binutils

Cary Coutant <ccoutant@google.com> writes:

> 2011-04-26 Cary Coutant  <ccoutant@google.com>
>
> 	* copy-relocs.cc (Copy_relocs::copy_reloc): Call make_copy_reloc
> 	instead of emit_copy_reloc.
> 	(Copy_relocs::emit_copy_reloc): Refactor.
> 	(Copy_relocs::make_copy_reloc): New function.
> 	(Copy_relocs::add_copy_reloc): Remove.
> 	* copy-relocs.h (Copy_relocs::emit_copy_reloc): Move to public
> 	section.
> 	(Copy_relocs::make_copy_reloc): New function.
> 	(Copy_relocs::add_copy_reloc): Remove.
> 	* gold.cc (queue_middle_tasks): Emit old COPY relocations from
> 	unchanged input files.
> 	* incremental-dump.cc (dump_incremental_inputs): Print "COPY" flag.
> 	* incremental.cc (Sized_incremental_binary::do_reserve_layout):
> 	Reserve BSS space for COPY relocations.
> 	(Sized_incremental_binary::do_emit_copy_relocs): New function.
> 	(Output_section_incremental_inputs::write_info_blocks): Record
> 	whether a symbol is copied from a shared object.
> 	(Sized_incr_dynobj::do_add_symbols): Record COPY relocations.
> 	* incremental.h
> 	(Incremental_input_entry_reader::get_output_symbol_index): Add
> 	is_copy parameter.
> 	(Incremental_binary::emit_copy_relocs): New function.
> 	(Incremental_binary::do_emit_copy_relocs): New function.
> 	(Sized_incremental_binary::Sized_incremental_binary): Initialize
> 	new data member.
> 	(Sized_incremental_binary::add_copy_reloc): New function.
> 	(Sized_incremental_binary::do_emit_copy_relocs): New function.
> 	(Sized_incremental_binary::Copy_reloc): New struct.
> 	(Sized_incremental_binary::Copy_relocs): New typedef.
> 	(Sized_incremental_binary::copy_relocs_): New data member.
> 	* symtab.cc (Symbol_table::add_from_incrobj): Change return type.
> 	* symtab.h (Symbol_table::add_from_incrobj): Change return type.
> 	* target.h (Sized_target::emit_copy_reloc): New function.
> 	* x86_64.cc (Target_x86_64::emit_copy_reloc): New function.


>  		if (sym->source() == Symbol::FROM_OBJECT
>  		    && sym->object() == obj
>  		    && sym->is_defined())
> -		  def_flag = 1U << 31;
> +		  def_flag = 2U << 30;
> +		else if (sym->is_copied_from_dynobj()
> +			 && this->symtab_->get_copy_source(sym) == dynobj)
> +		  def_flag = 3U << 30;

Let's give some names to 1U, 2U, 3U, and 30.

> -      *is_def = (output_symndx & (1U << 31)) != 0;
> -      return output_symndx & ((1U << 31) - 1);
> +      *is_def = (output_symndx >> 31) == 1;
> +      *is_copy = (output_symndx >> 30) == 3;
> +      return output_symndx & ((1U << 30) - 1);

This is kind of tricky considering how the bits are set; better to use a
switch on output_symndx >> 30, I think.

This is OK with those changes.

Thanks.


> (I split a couple of patches and added a couple, so the total patch
> count is now up to 22.)

Don't think I didn't notice that you're up to 25 now.

Ian

^ permalink raw reply	[flat|nested] 3+ messages in thread

* Re: [gold patch] Incremental 17/22: COPY relocations
  2011-06-08  0:31 ` Ian Lance Taylor
@ 2011-06-08  3:54   ` Cary Coutant
  0 siblings, 0 replies; 3+ messages in thread
From: Cary Coutant @ 2011-06-08  3:54 UTC (permalink / raw)
  To: Ian Lance Taylor; +Cc: Binutils

>>               if (sym->source() == Symbol::FROM_OBJECT
>>                   && sym->object() == obj
>>                   && sym->is_defined())
>> -               def_flag = 1U << 31;
>> +               def_flag = 2U << 30;
>> +             else if (sym->is_copied_from_dynobj()
>> +                      && this->symtab_->get_copy_source(sym) == dynobj)
>> +               def_flag = 3U << 30;
>
> Let's give some names to 1U, 2U, 3U, and 30.

Done. I added these:

	* incremental.h (enum Incremental_shlib_symbol_flags): New type.
	(INCREMENTAL_SHLIB_SYM_FLAGS_SHIFT): New constant.

>> -      *is_def = (output_symndx & (1U << 31)) != 0;
>> -      return output_symndx & ((1U << 31) - 1);
>> +      *is_def = (output_symndx >> 31) == 1;
>> +      *is_copy = (output_symndx >> 30) == 3;
>> +      return output_symndx & ((1U << 30) - 1);
>
> This is kind of tricky considering how the bits are set; better to use a
> switch on output_symndx >> 30, I think.

Done.

> This is OK with those changes.

Thanks, committed. Updated ChangeLog below.

>> (I split a couple of patches and added a couple, so the total patch
>> count is now up to 22.)
>
> Don't think I didn't notice that you're up to 25 now.

Heh, heh. I'll stop numbering them now.

-cary


	* copy-relocs.cc (Copy_relocs::copy_reloc): Call make_copy_reloc
	instead of emit_copy_reloc.
	(Copy_relocs::emit_copy_reloc): Refactor.
	(Copy_relocs::make_copy_reloc): New function.
	(Copy_relocs::add_copy_reloc): Remove.
	* copy-relocs.h (Copy_relocs::emit_copy_reloc): Move to public
	section.
	(Copy_relocs::make_copy_reloc): New function.
	(Copy_relocs::add_copy_reloc): Remove.
	* gold.cc (queue_middle_tasks): Emit old COPY relocations from
	unchanged input files.
	* incremental-dump.cc (dump_incremental_inputs): Print "COPY" flag.
	* incremental.cc (Sized_incremental_binary::do_reserve_layout):
	Reserve BSS space for COPY relocations.
	(Sized_incremental_binary::do_emit_copy_relocs): New function.
	(Output_section_incremental_inputs::write_info_blocks): Record
	whether a symbol is copied from a shared object.
	(Sized_incr_dynobj::do_add_symbols): Record COPY relocations.
	* incremental.h (enum Incremental_shlib_symbol_flags): New type.
	(INCREMENTAL_SHLIB_SYM_FLAGS_SHIFT): New constant.
	(Incremental_input_entry_reader::get_output_symbol_index): Add
	is_copy parameter.
	(Incremental_binary::emit_copy_relocs): New function.
	(Incremental_binary::do_emit_copy_relocs): New function.
	(Sized_incremental_binary::Sized_incremental_binary): Initialize
	new data member.
	(Sized_incremental_binary::add_copy_reloc): New function.
	(Sized_incremental_binary::do_emit_copy_relocs): New function.
	(Sized_incremental_binary::Copy_reloc): New struct.
	(Sized_incremental_binary::Copy_relocs): New typedef.
	(Sized_incremental_binary::copy_relocs_): New data member.
	* symtab.cc (Symbol_table::add_from_incrobj): Change return type.
	* symtab.h (Symbol_table::add_from_incrobj): Change return type.
	* target.h (Sized_target::emit_copy_reloc): New function.
	* x86_64.cc (Target_x86_64::emit_copy_reloc): New function.

^ permalink raw reply	[flat|nested] 3+ messages in thread

end of thread, other threads:[~2011-06-08  3:54 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2011-04-26 23:57 [gold patch] Incremental 17/22: COPY relocations Cary Coutant
2011-06-08  0:31 ` Ian Lance Taylor
2011-06-08  3:54   ` Cary Coutant

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).