// ehframe.h -- handle exception frame sections for gold  -*- C++ -*-

// Copyright (C) 2006-2018 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_EHFRAME_H
#define GOLD_EHFRAME_H

#include <map>
#include <set>
#include <vector>

#include "output.h"
#include "merge.h"

namespace gold
{

template<int size, bool big_endian>
class Track_relocs;

class Eh_frame;

// This class manages the .eh_frame_hdr section, which holds the data
// for the PT_GNU_EH_FRAME segment.  gcc's unwind support code uses
// the PT_GNU_EH_FRAME segment to find the list of FDEs.  This saves
// the time required to register the exception handlers at startup
// time and when a shared object is loaded, and the time required to
// deregister the exception handlers when a shared object is unloaded.

class Eh_frame_hdr : public Output_section_data
{
 public:
  Eh_frame_hdr(Output_section* eh_frame_section, const Eh_frame*);

  // Record that we found an unrecognized .eh_frame section.
  void
  found_unrecognized_eh_frame_section()
  { this->any_unrecognized_eh_frame_sections_ = true; }

  // Record an FDE.
  void
  record_fde(section_offset_type fde_offset, unsigned char fde_encoding)
  {
    if (!this->any_unrecognized_eh_frame_sections_)
      this->fde_offsets_.push_back(std::make_pair(fde_offset, fde_encoding));
  }

 protected:
  // Set the final data size.
  void
  set_final_data_size();

  // Write the data to the file.
  void
  do_write(Output_file*);

  // Write to a map file.
  void
  do_print_to_mapfile(Mapfile* mapfile) const
  { mapfile->print_output_data(this, _("** eh_frame_hdr")); }

 private:
  // Write the data to the file with the right endianness.
  template<int size, bool big_endian>
  void
  do_sized_write(Output_file*);

  // The data we record for one FDE: the offset of the FDE within the
  // .eh_frame section, and the FDE encoding.
  typedef std::pair<section_offset_type, unsigned char> Fde_offset;

  // The list of information we record for an FDE.
  typedef std::vector<Fde_offset> Fde_offsets;

  // When writing out the header, we convert the FDE offsets into FDE
  // addresses.  This is a list of pairs of the offset from the header
  // to the FDE PC and to the FDE itself.
  template<int size>
  class Fde_addresses
  {
   public:
    typedef typename elfcpp::Elf_types<size>::Elf_Addr Address;
    typedef typename std::pair<Address, Address> Fde_address;
    typedef typename std::vector<Fde_address> Fde_address_list;
    typedef typename Fde_address_list::iterator iterator;

    Fde_addresses(unsigned int reserve)
      : fde_addresses_()
    { this->fde_addresses_.reserve(reserve); }

    void
    push_back(Address pc_address, Address fde_address)
    {
      this->fde_addresses_.push_back(std::make_pair(pc_address, fde_address));
    }

    iterator
    begin()
    { return this->fde_addresses_.begin(); }

    iterator
    end()
    { return this->fde_addresses_.end(); }

   private:
    Fde_address_list fde_addresses_;
  };

  // Compare Fde_address objects.
  template<int size>
  struct Fde_address_compare
  {
    bool
    operator()(const typename Fde_addresses<size>::Fde_address& f1,
	       const typename Fde_addresses<size>::Fde_address& f2) const
    { return f1.first < f2.first; }
  };

  // Return the PC to which an FDE refers.
  template<int size, bool big_endian>
  typename elfcpp::Elf_types<size>::Elf_Addr
  get_fde_pc(typename elfcpp::Elf_types<size>::Elf_Addr eh_frame_address,
	     const unsigned char* eh_frame_contents,
	     section_offset_type fde_offset, unsigned char fde_encoding);

  // Convert Fde_offsets to Fde_addresses.
  template<int size, bool big_endian>
  void
  get_fde_addresses(Output_file* of,
		    const Fde_offsets* fde_offsets,
		    Fde_addresses<size>* fde_addresses);

  // The .eh_frame section.
  Output_section* eh_frame_section_;
  // The .eh_frame section data.
  const Eh_frame* eh_frame_data_;
  // Data from the FDEs in the .eh_frame sections.
  Fde_offsets fde_offsets_;
  // Whether we found any .eh_frame sections which we could not
  // process.
  bool any_unrecognized_eh_frame_sections_;
};

// This class holds an FDE.

class Fde
{
 public:
  Fde(Relobj* object, unsigned int shndx, section_offset_type input_offset,
      const unsigned char* contents, size_t length)
    : object_(object),
      contents_(reinterpret_cast<const char*>(contents), length)
  {
    this->u_.from_object.shndx = shndx;
    this->u_.from_object.input_offset = input_offset;
  }

  // Create an FDE associated with a PLT.
  Fde(Output_data* plt, const unsigned char* contents, size_t length,
      bool post_map)
    : object_(NULL),
      contents_(reinterpret_cast<const char*>(contents), length)
  {
    this->u_.from_linker.plt = plt;
    this->u_.from_linker.post_map = post_map;
  }

  // Return the length of this FDE.  Add 4 for the length and 4 for
  // the offset to the CIE.
  size_t
  length() const
  { return this->contents_.length() + 8; }

  // Add a mapping for this FDE to MERGE_MAP, so that relocations
  // against the FDE are applied to right part of the output file.
  void
  add_mapping(section_offset_type output_offset,
              Output_section_data* output_data) const
  {
    if (this->object_ != NULL)
      this->object_->add_merge_mapping(output_data, this->u_.from_object.shndx,
			     this->u_.from_object.input_offset, this->length(),
			     output_offset);
  }

  // Return whether this FDE was added after merge mapping.
  bool
  post_map()
  { return this->object_ == NULL && this->u_.from_linker.post_map; }

  // Write the FDE to OVIEW starting at OFFSET.  FDE_ENCODING is the
  // encoding, from the CIE.  Round up the bytes to ADDRALIGN if
  // necessary.  ADDRESS is the virtual address of OVIEW.  Record the
  // FDE in EH_FRAME_HDR.  Return the new offset.
  template<int size, bool big_endian>
  section_offset_type
  write(unsigned char* oview, section_offset_type output_section_offset,
	section_offset_type offset, uint64_t address, unsigned int addralign,
	section_offset_type cie_offset, unsigned char fde_encoding,
	Eh_frame_hdr* eh_frame_hdr);

  bool operator==(const Fde&) const;

 private:
  // The object in which this FDE was seen.  This will be NULL for a
  // linker generated FDE.
  Relobj* object_;
  union
  {
    // These fields are used if the FDE is from an input object (the
    // object_ field is not NULL).
    struct
    {
      // Input section index for this FDE.
      unsigned int shndx;
      // Offset within the input section for this FDE.
      section_offset_type input_offset;
    } from_object;
    // This field is used if the FDE is generated by the linker (the
    // object_ field is NULL).
    struct
    {
      // The only linker generated FDEs are for PLT sections, and this
      // points to the PLT section.
      Output_data* plt;
      // Set if the FDE was added after merge mapping.
      bool post_map;
    } from_linker;
  } u_;
  // FDE data.
  std::string contents_;
};

// A FDE plus some info from a CIE to allow later writing of the FDE.

struct Post_fde
{
  Post_fde(Fde* f, section_offset_type cie_off, unsigned char encoding)
    : fde(f), cie_offset(cie_off), fde_encoding(encoding)
  { }

  Fde* fde;
  section_offset_type cie_offset;
  unsigned char fde_encoding;
};

typedef std::vector<Post_fde> Post_fdes;

// This class holds a CIE.

class Cie
{
 public:
  Cie(Relobj* object, unsigned int shndx, section_offset_type input_offset,
      unsigned char fde_encoding, const char* personality_name,
      const unsigned char* contents, size_t length)
    : object_(object),
      shndx_(shndx),
      input_offset_(input_offset),
      fde_encoding_(fde_encoding),
      personality_name_(personality_name),
      fdes_(),
      contents_(reinterpret_cast<const char*>(contents), length)
  { }

  ~Cie();

  // We permit copying a CIE when there are no FDEs.  This is
  // convenient in the code which creates them.
  Cie(const Cie& cie)
    : object_(cie.object_),
      shndx_(cie.shndx_),
      input_offset_(cie.input_offset_),
      fde_encoding_(cie.fde_encoding_),
      personality_name_(cie.personality_name_),
      fdes_(),
      contents_(cie.contents_)
  { gold_assert(cie.fdes_.empty()); }

  // Add an FDE associated with this CIE.
  void
  add_fde(Fde* fde)
  { this->fdes_.push_back(fde); }

  // Remove an FDE associated with this CIE.  Only the last FDE may be removed.
  void
  remove_fde(const Fde*);

  // Return the number of FDEs.
  unsigned int
  fde_count() const
  { return this->fdes_.size(); }

  // Set the output offset of this CIE to OUTPUT_OFFSET.  It will be
  // followed by all its FDEs.  ADDRALIGN is the required address
  // alignment, typically 4 or 8.  This updates MERGE_MAP with the
  // mapping.  It returns the new output offset.
  section_offset_type
  set_output_offset(section_offset_type output_offset, unsigned int addralign,
		    Output_section_data*);

  // Write the CIE to OVIEW starting at OFFSET.  Round up the bytes to
  // ADDRALIGN.  ADDRESS is the virtual address of OVIEW.
  // EH_FRAME_HDR is the exception frame header for FDE recording.
  // POST_FDES stashes FDEs created after mappings were done, for later
  // writing.  Return the new offset.
  template<int size, bool big_endian>
  section_offset_type
  write(unsigned char* oview, section_offset_type output_section_offset,
	section_offset_type offset, uint64_t address,
	unsigned int addralign, Eh_frame_hdr* eh_frame_hdr,
	Post_fdes* post_fdes);

  // Return the FDE encoding.
  unsigned char
  fde_encoding() const
  { return this->fde_encoding_; }

  friend bool operator<(const Cie&, const Cie&);
  friend bool operator==(const Cie&, const Cie&);

 private:
  // The class is not assignable.
  Cie& operator=(const Cie&);

  // The object in which this CIE was first seen.  This will be NULL
  // for a linker generated CIE.
  Relobj* object_;
  // Input section index for this CIE.  This will be 0 for a linker
  // generated CIE.
  unsigned int shndx_;
  // Offset within the input section for this CIE.  This will be 0 for
  // a linker generated CIE.
  section_offset_type input_offset_;
  // The encoding of the FDE.  This is a DW_EH_PE code.
  unsigned char fde_encoding_;
  // The name of the personality routine.  This will be the name of a
  // global symbol, or will be the empty string.
  std::string personality_name_;
  // List of FDEs.
  std::vector<Fde*> fdes_;
  // CIE data.
  std::string contents_;
};

extern bool operator<(const Cie&, const Cie&);
extern bool operator==(const Cie&, const Cie&);

// This class manages .eh_frame sections.  It discards duplicate
// exception information.

class Eh_frame : public Output_section_data
{
 public:
  enum Eh_frame_section_disposition
  {
    EH_EMPTY_SECTION,
    EH_UNRECOGNIZED_SECTION,
    EH_OPTIMIZABLE_SECTION,
    EH_END_MARKER_SECTION
  };

  Eh_frame();

  // Record the associated Eh_frame_hdr, if any.
  void
  set_eh_frame_hdr(Eh_frame_hdr* hdr)
  { this->eh_frame_hdr_ = hdr; }

  // Add the input section SHNDX in OBJECT.  SYMBOLS is the contents
  // of the symbol table section (size SYMBOLS_SIZE), SYMBOL_NAMES is
  // the symbol names section (size SYMBOL_NAMES_SIZE).  RELOC_SHNDX
  // is the relocation section if any (0 for none, -1U for multiple).
  // RELOC_TYPE is the type of the relocation section if any.  This
  // returns whether the section was incorporated into the .eh_frame
  // data.
  template<int size, bool big_endian>
  Eh_frame_section_disposition
  add_ehframe_input_section(Sized_relobj_file<size, big_endian>* object,
			    const unsigned char* symbols,
			    section_size_type symbols_size,
			    const unsigned char* symbol_names,
			    section_size_type symbol_names_size,
			    unsigned int shndx, unsigned int reloc_shndx,
			    unsigned int reloc_type);

  // Add a CIE and an FDE for a PLT section, to permit unwinding
  // through a PLT.  The FDE data should start with 8 bytes of zero,
  // which will be replaced by a 4 byte PC relative reference to the
  // address of PLT and a 4 byte size of PLT.
  void
  add_ehframe_for_plt(Output_data* plt, const unsigned char* cie_data,
		      size_t cie_length, const unsigned char* fde_data,
		      size_t fde_length);

  // Remove unwind information for a PLT.  Only the last FDE added may
  // be removed.
  void
  remove_ehframe_for_plt(Output_data* plt, const unsigned char* cie_data,
			 size_t cie_length, const unsigned char* fde_data,
			 size_t fde_length);

  // Return the number of FDEs.
  unsigned int
  fde_count() const;

 protected:
  // Set the final data size.
  void
  set_final_data_size();

  // Return the output address for an input address.
  bool
  do_output_offset(const Relobj*, unsigned int shndx,
		   section_offset_type offset,
		   section_offset_type* poutput) const;

  // Write the data to the file.
  void
  do_write(Output_file*);

  // Write to a map file.
  void
  do_print_to_mapfile(Mapfile* mapfile) const
  { mapfile->print_output_data(this, _("** eh_frame")); }

 private:
  // The comparison routine for the CIE map.
  struct Cie_less
  {
    bool
    operator()(const Cie* cie1, const Cie* cie2) const
    { return *cie1 < *cie2; }
  };

  // A set of unique CIEs.
  typedef std::set<Cie*, Cie_less> Cie_offsets;

  // A list of unmergeable CIEs.
  typedef std::vector<Cie*> Unmergeable_cie_offsets;

  // A mapping from offsets to CIEs.  This is used while reading an
  // input section.
  typedef std::map<uint64_t, Cie*> Offsets_to_cie;

  // A list of CIEs, and a bool indicating whether the CIE is
  // mergeable.
  typedef std::vector<std::pair<Cie*, bool> > New_cies;

  // Skip an LEB128.
  static bool
  skip_leb128(const unsigned char**, const unsigned char*);

  // The implementation of add_ehframe_input_section.
  template<int size, bool big_endian>
  bool
  do_add_ehframe_input_section(Sized_relobj_file<size, big_endian>* object,
			       const unsigned char* symbols,
			       section_size_type symbols_size,
			       const unsigned char* symbol_names,
			       section_size_type symbol_names_size,
			       unsigned int shndx,
			       unsigned int reloc_shndx,
			       unsigned int reloc_type,
			       const unsigned char* pcontents,
			       section_size_type contents_len,
			       New_cies*);

  // Read a CIE.
  template<int size, bool big_endian>
  bool
  read_cie(Sized_relobj_file<size, big_endian>* object,
	   unsigned int shndx,
	   const unsigned char* symbols,
	   section_size_type symbols_size,
	   const unsigned char* symbol_names,
	   section_size_type symbol_names_size,
	   const unsigned char* pcontents,
	   const unsigned char* pcie,
	   const unsigned char* pcieend,
	   Track_relocs<size, big_endian>* relocs,
	   Offsets_to_cie* cies,
	   New_cies* new_cies);

  // Read an FDE.
  template<int size, bool big_endian>
  bool
  read_fde(Sized_relobj_file<size, big_endian>* object,
	   unsigned int shndx,
	   const unsigned char* symbols,
	   section_size_type symbols_size,
	   const unsigned char* pcontents,
	   unsigned int offset,
	   const unsigned char* pfde,
	   const unsigned char* pfdeend,
	   Track_relocs<size, big_endian>* relocs,
	   Offsets_to_cie* cies);

  // Template version of write function.
  template<int size, bool big_endian>
  void
  do_sized_write(unsigned char* oview);

  // The exception frame header, if any.
  Eh_frame_hdr* eh_frame_hdr_;
  // A mapping from all unique CIEs to their offset in the output
  // file.
  Cie_offsets cie_offsets_;
  // A mapping from unmergeable CIEs to their offset in the output
  // file.
  Unmergeable_cie_offsets unmergeable_cie_offsets_;
  // Whether we have created the mappings to the output section.
  bool mappings_are_done_;
  // The final data size.  This is only set if mappings_are_done_ is
  // true.
  section_size_type final_data_size_;
};

} // End namespace gold.

#endif // !defined(GOLD_EHFRAME_H)
