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

// Copyright (C) 2006-2021 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),
      dynrelro_(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 writable variables which require COPY relocations are placed.
  Output_data_space* dynbss_;
  // The dynamic read-only data, which goes into the .data.rel.ro section.
  // This is where read-only variables which require COPY relocations are
  // placed.
  Output_data_space* dynrelro_;
};

} // End namespace gold.

#endif // !defined(GOLD_COPY_RELOCS_H)
