// copy-relocs.h -- handle COPY relocations for gold   -*- C++ -*-

// Copyright (C) 2006-2016 Free Software Foundation, Inc.
// Written by Ian Lance Taylor <iant@google.com>.

// This file is part of gold.

// This program is free software; you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation; either version 3 of the License, or
// (at your option) any later version.

// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU General Public License for more details.

// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
// MA 02110-1301, USA.

#ifndef GOLD_COPY_RELOCS_H
#define GOLD_COPY_RELOCS_H

#include "elfcpp.h"
#include "reloc-types.h"
#include "output.h"

namespace gold
{

// This class is used to manage COPY relocations.  We try to avoid
// them when possible.  A COPY relocation may be required when an
// executable refers to a variable defined in a shared library.  COPY
// relocations are problematic because they tie the executable to the
// exact size of the variable in the shared library.  We can avoid
// them if all the references to the variable are in a writeable
// section.  In that case we can simply use dynamic relocations.
// However, when scanning relocs, we don't know when we see the
// relocation whether we will be forced to use a COPY relocation or
// not.  So we have to save the relocation during the reloc scanning,
// and then emit it as a dynamic relocation if necessary.  This class
// implements that.  It is used by the target specific code.

// The template parameter SH_TYPE is the type of the reloc section to
// be used for COPY relocs: elfcpp::SHT_REL or elfcpp::SHT_RELA.

template<int sh_type, int size, bool big_endian>
class Copy_relocs
{
 private:
  typedef typename Reloc_types<sh_type, size, big_endian>::Reloc Reloc;

 public:
  Copy_relocs(unsigned int copy_reloc_type)
    : entries_(), copy_reloc_type_(copy_reloc_type), dynbss_(NULL)
  { }

  // This is called while scanning relocs if we see a relocation
  // against a symbol which may force us to generate a COPY reloc.
  // SYM is the symbol.  OBJECT is the object whose relocs we are
  // scanning.  The relocation is being applied to section SHNDX in
  // OBJECT.  OUTPUT_SECTION is the output section where section SHNDX
  // will wind up.  REL is the reloc itself.  The Output_data_reloc
  // section is where the dynamic relocs are put.
  void
  copy_reloc(Symbol_table*,
	     Layout*,
	     Sized_symbol<size>* sym,
             Sized_relobj_file<size, big_endian>* object,
	     unsigned int shndx,
	     Output_section* output_section,
	     unsigned int r_type,
	     typename elfcpp::Elf_types<size>::Elf_Addr r_offset,
	     typename elfcpp::Elf_types<size>::Elf_Swxword r_addend,
	     Output_data_reloc<sh_type, true, size, big_endian>*);

  // Return whether there are any saved relocations.
  bool
  any_saved_relocs() const
  { return !this->entries_.empty(); }

  // Emit any saved relocations which turn out to be needed.  This is
  // called after all the relocs have been scanned.
  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>*);

 protected:
  typedef typename elfcpp::Elf_types<size>::Elf_Addr Address;
  typedef typename elfcpp::Elf_types<size>::Elf_Addr Addend;

  // This POD class holds the relocations we are saving.  We will emit
  // these relocations if it turns out that the symbol does not
  // require a COPY relocation.
  struct Copy_reloc_entry
  {
    Copy_reloc_entry(Symbol* sym, unsigned int reloc_type,
		     Sized_relobj_file<size, big_endian>* relobj,
                     unsigned int shndx,
		     Output_section* output_section,
		     Address address, Addend addend)
      : sym_(sym), reloc_type_(reloc_type), relobj_(relobj),
	shndx_(shndx), output_section_(output_section),
	address_(address), addend_(addend)
    { }

    Symbol* sym_;
    unsigned int reloc_type_;
    Sized_relobj_file<size, big_endian>* relobj_;
    unsigned int shndx_;
    Output_section* output_section_;
    Address address_;
    Addend addend_;
  };

  // Make a new COPY reloc and emit it.
  void
  make_copy_reloc(Symbol_table*, Layout*, Sized_symbol<size>*,
		  Sized_relobj_file<size, big_endian>* object,
		  Output_data_reloc<sh_type, true, size, big_endian>*);

  // A list of relocs to be saved.
  typedef std::vector<Copy_reloc_entry> Copy_reloc_entries;

  // The list of relocs we are saving.
  Copy_reloc_entries entries_;

 private:
  // Return whether we need a COPY reloc.
  bool
  need_copy_reloc(Sized_symbol<size>* gsym,
                  Sized_relobj_file<size, big_endian>* object,
		  unsigned int shndx) const;

  // Save a reloc against SYM for possible emission later.
  void
  save(Symbol*,
       Sized_relobj_file<size, big_endian>*,
       unsigned int shndx,
       Output_section*,
       unsigned int r_type,
       typename elfcpp::Elf_types<size>::Elf_Addr r_offset,
       typename elfcpp::Elf_types<size>::Elf_Swxword r_addend);

  // The target specific relocation type of the COPY relocation.
  const unsigned int copy_reloc_type_;
  // The dynamic BSS data which goes into the .bss section.  This is
  // where variables which require COPY relocations are placed.
  Output_data_space* dynbss_;
};

} // End namespace gold.

#endif // !defined(GOLD_COPY_RELOCS_H)
