// arm-reloc-property.h -- ARM relocation properties   -*- C++ -*-

// Copyright (C) 2010-2021 Free Software Foundation, Inc.
// Written by Doug Kwan <dougkwan@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_ARM_RELOC_PROPERTY_H
#define GOLD_ARM_RELOC_PROPERTY_H

namespace gold
{
// The Arm_reloc_property class is to store information about a particular
// relocation code.

class Arm_reloc_property
{
 public:
  // Types of relocation codes.
  enum Reloc_type {
    RT_NONE,		// No relocation type.
    RT_STATIC,	// Relocations processed by static linkers.
    RT_DYNAMIC,	// Relocations processed by dynamic linkers.
    RT_PRIVATE,	// Private relocations, not supported by gold.
    RT_OBSOLETE	// Obsolete relocations that should not be used.
  };

  // Classes of relocation codes.
  enum Reloc_class {
    RC_NONE,	// No relocation class.
    RC_DATA,	// Data relocation.
    RC_ARM,	// ARM instruction relocation.
    RC_THM16,	// 16-bit THUMB instruction relocation.
    RC_THM32,	// 32-bit THUMB instruction relocation.
    RC_MISC	// Miscellaneous class.
  };

  // Types of bases of relative addressing relocation codes.
  enum Relative_address_base {
    RAB_NONE,		// Relocation is not relative addressing
    RAB_B_S,		// Address origin of output segment of defining symbol.
    RAB_DELTA_B_S,	// Change of address origin.
    RAB_GOT_ORG,	// Origin of GOT.
    RAB_P,		// Address of the place being relocated.
    RAB_Pa,		// Adjusted address (P & 0xfffffffc).
    RAB_TLS,		// Thread local storage.
    RAB_tp		// Thread pointer.
  };

  // Relocation code represented by this.
  unsigned int
  code() const
  { return this->code_; }

  // Name of the relocation code.
  const std::string&
  name() const
  { return this->name_; }
  
  // Type of relocation code.
  Reloc_type
  reloc_type() const
  { return this->reloc_type_; }

  // Whether this code is deprecated.
  bool
  is_deprecated() const
  { return this->is_deprecated_; }

  // Class of relocation code.
  Reloc_class
  reloc_class() const
  { return this->reloc_class_; }

  // Whether this code is implemented in gold.
  bool
  is_implemented() const
  { return this->is_implemented_; }

  // If code is a group relocation code, return the group number, otherwise -1.
  int
  group_index() const
  { return this->group_index_; }

  // Whether relocation checks for overflow.
  bool
  checks_overflow() const
  { return this->checks_overflow_; }

  // Return size of relocation.
  size_t
  size() const
  { return this->size_; }

  // Return alignment of relocation.
  size_t
  align() const
  { return this->align_; }

  // Whether relocation use a GOT entry.
  bool
  uses_got_entry() const
  { return this->uses_got_entry_; }

  // Whether relocation use a GOT origin.
  bool
  uses_got_origin() const
  { return this->uses_got_origin_; }
  
  // Whether relocation uses the Thumb-bit in a symbol address.
  bool
  uses_thumb_bit() const
  { return this->uses_thumb_bit_; }

  // Whether relocation uses the symbol base.
  bool
  uses_symbol_base() const
  { return this->uses_symbol_base_; }

  // Whether relocation uses the symbol.
  bool
  uses_symbol() const
  { return this->uses_symbol_; }

  // Return the type of relative address base or RAB_NONE if this
  // is not a relative addressing relocation.
  Relative_address_base
  relative_address_base() const
  { return this->relative_address_base_; } 

 protected:
  // These are protected.  We only allow Arm_reloc_property_table to
  // manage Arm_reloc_property. 
  Arm_reloc_property(unsigned int code, const char* name, Reloc_type rtype,
		     bool is_deprecated, Reloc_class rclass,
		     const std::string& operation, bool is_implemented,
		     int group_index, bool checks_overflow);

  friend class Arm_reloc_property_table;
  
 private:
  // Copying is not allowed.
  Arm_reloc_property(const Arm_reloc_property&);
  Arm_reloc_property& operator=(const Arm_reloc_property&);

  // The Tree_node class is used to represent parsed relocation operations. 
  // We look at Trees to extract information about relocation operations.
  class Tree_node
  {
   public:
    typedef std::vector<Tree_node*> Tree_node_vector;

    // Construct a leaf node.
    Tree_node(const char* name)
      : is_leaf_(true), name_(name), children_()
    { }

    // Construct an internal node.  A node owns all its children and is
    // responsible for releasing them at its own destruction.
    Tree_node(Tree_node_vector::const_iterator begin,
	      Tree_node_vector::const_iterator end)
      : is_leaf_(false), name_(), children_()
    {
      for (Tree_node_vector::const_iterator p = begin; p != end; ++p)
	this->children_.push_back(*p);
    }

    ~Tree_node()
    {
      for(size_t i = 0; i <this->children_.size(); ++i)
	delete this->children_[i];
    }

    // Whether this is a leaf node.
    bool
    is_leaf() const
    { return this->is_leaf_; }

    // Return name of this.  This is only valid for a leaf node.
    const std::string&
    name() const
    {
      gold_assert(this->is_leaf_);
      return this->name_;
    }

    // Return the number of children.  This is only valid for a non-leaf node.
    size_t
    number_of_children() const
    {
      gold_assert(!this->is_leaf_);
      return this->children_.size();
    }

    // Return the i-th child of this.  This is only valid for a non-leaf node.
    Tree_node*
    child(size_t i) const
    {
      gold_assert(!this->is_leaf_ && i < this->children_.size());
      return this->children_[i];
    }

    // Parse an S-expression string and build a tree and return the root node.
    // Caller is responsible for releasing tree after use.
    static Tree_node*
    make_tree(const std::string&);

    // Convert a tree back to an S-expression string.
    std::string
    s_expression() const
    {
      if (this->is_leaf_)
	return this->name_;

      // Concatenate S-expressions of children. Enclose them with
      // a pair of parentheses and use space as token delimiters.
      std::string s("(");
      for(size_t i = 0; i <this->children_.size(); ++i)
	s = s + " " + this->children_[i]->s_expression();
      return s + " )";
    }

   private:
    // Whether this is a leaf node.
    bool is_leaf_;
    // Name of this if this is a leaf node.
    std::string name_;
    // Children of this if this a non-leaf node.
    Tree_node_vector children_;
  };

  // Relocation code.
  unsigned int code_;
  // Relocation name.
  std::string name_;
  // Type of relocation.
  Reloc_type reloc_type_;
  // Class of relocation.
  Reloc_class reloc_class_;
  // Group index (0, 1, or 2) if this is a group relocation or -1 otherwise.
  int group_index_; 
  // Size of relocation.
  size_t size_;
  // Alignment of relocation.
  size_t align_;
  // Relative address base.
  Relative_address_base relative_address_base_;
  // Whether this is deprecated.
  bool is_deprecated_ : 1;
  // Whether this is implemented in gold.
  bool is_implemented_ : 1;
  // Whether this checks overflow.
  bool checks_overflow_ : 1;
  // Whether this uses a GOT entry.
  bool uses_got_entry_ : 1;
  // Whether this uses a GOT origin.
  bool uses_got_origin_ : 1;
  // Whether this uses a PLT entry.
  bool uses_plt_entry_ : 1;
  // Whether this uses the THUMB bit in symbol address.
  bool uses_thumb_bit_ : 1;
  // Whether this uses the symbol base.
  bool uses_symbol_base_ : 1;
  // Whether this uses an addend.
  bool uses_addend_ : 1;
  // Whether this uses the symbol.
  bool uses_symbol_ : 1;
};

// Arm_reloc_property_table.  This table is used for looking up properties
// of relocation types.  The table entries are initialized using information
// from arm-reloc.def.

class Arm_reloc_property_table
{
 public:
  Arm_reloc_property_table();

  // Return an Arm_reloc_property object for CODE if it is a valid relocation
  // code or NULL otherwise.
  const Arm_reloc_property*
  get_reloc_property(unsigned int code) const
  {
    gold_assert(code < Property_table_size);
    return this->table_[code];
  }

  // Like get_reloc_property but only return non-NULL if relocation code is
  // static and implemented.
  const Arm_reloc_property*
  get_implemented_static_reloc_property(unsigned int code) const
  {
    gold_assert(code < Property_table_size);
    const Arm_reloc_property* arp = this->table_[code];
    return ((arp != NULL
	     && (arp->reloc_type() == Arm_reloc_property::RT_STATIC)
	     && arp->is_implemented())
	    ? arp
	    : NULL);
  }
  
  // Return a string describing the relocation code that is not
  // an implemented static reloc code.
  std::string
  reloc_name_in_error_message(unsigned int code);

 private:
  // Copying is not allowed.
  Arm_reloc_property_table(const Arm_reloc_property_table&);
  Arm_reloc_property_table& operator=(const Arm_reloc_property_table&);

  // The Parse_expression class is used to convert relocation operations in
  // arm-reloc.def into S-expression strings, which are parsed again to
  // build actual expression trees.  We do not build the expression trees
  // directly because the parser for operations in arm-reloc.def is simpler
  // this way.  Conversion from S-expressions to trees is simple.
  class Parse_expression
  {
   public:
    // Construction a Parse_expression with an S-expression string.
    Parse_expression(const std::string& s_expression)
      : s_expression_(s_expression)
    { }

    // Value of this expression as an S-expression string.
    const std::string&
    s_expression() const
    { return this->s_expression_; }

    // We want to overload operators used in relocation operations so
    // that we can execute operations in arm-reloc.def to generate
    // S-expressions directly.
#define DEF_OPERATOR_OVERLOAD(op) \
    Parse_expression \
    operator op (const Parse_expression& e) \
    { \
      return Parse_expression("( " #op " " + this->s_expression_ + " " + \
			      e.s_expression_ + " )"); \
    }

    // Operator appearing in relocation operations in arm-reloc.def.
    DEF_OPERATOR_OVERLOAD(+)
    DEF_OPERATOR_OVERLOAD(-)
    DEF_OPERATOR_OVERLOAD(|)
    
   private:
    // This represented as an S-expression string.
    std::string s_expression_;
  };

#define DEF_RELOC_FUNC(name) \
  static Parse_expression \
  (name)(const Parse_expression& arg) \
  { return Parse_expression("( " #name " " + arg.s_expression() + " )"); }

  // Functions appearing in relocation operations in arm-reloc.def.
  DEF_RELOC_FUNC(B)
  DEF_RELOC_FUNC(DELTA_B)
  DEF_RELOC_FUNC(GOT)
  DEF_RELOC_FUNC(Module)
  DEF_RELOC_FUNC(PLT)

  static const unsigned int Property_table_size = 256;

  // The property table.
  Arm_reloc_property* table_[Property_table_size];
};

} // End namespace gold.

#endif // !defined(GOLD_ARM_RELOC_PROPERTY_H)
