// aarch64-reloc-property.h -- AArch64 relocation properties   -*- C++ -*-

// Copyright (C) 2014 Free Software Foundation, Inc.
// Written by Han Shen <shenhan@google.com> and Jing Yu <jingyu@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_AARCH64_RELOC_PROPERTY_H
#define GOLD_AARCH64_RELOC_PROPERTY_H

#include<vector>
#include<string>

#include"aarch64.h"

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

class AArch64_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.
  };

  // Classes of relocation codes.
  enum Reloc_class {
    RC_NONE,		// No relocation class.
    RC_DATA,		// Data relocation.
    RC_AARCH64,		// Static AArch64 relocations
    RC_CFLOW,		// Control flow
    RC_TLS,		// Thread local storage
    RC_DYNAMIC,		// Dynamic relocation
  };

  // Instructions that are associated with relocations.
  enum Reloc_inst {
    INST_DATA = 0,
    INST_MOVW = 1,	// movz, movk, movn
    INST_LD = 2,	// ld literal
    INST_ADR = 3,	// adr
    INST_ADRP = 4,	// adrp
    INST_ADD = 5,	// add
    INST_LDST = 6,	// ld/st
    INST_TBZNZ = 7,	// tbz/tbnz
    INST_CONDB = 8,	// B.cond
    INST_B = 9,		// b  [25:0]
    INST_CALL = 10,	// bl [25:0]
    INST_NUM = 11,	// total number of entries in the table
  };

  // Types of bases of relative addressing relocation codes.
  // enum Relative_address_base {
  //   RAB_NONE,		// Relocation is not relative addressing
  // };

  typedef bool (*rvalue_checkup_func_p)(int64_t);
  typedef uint64_t (*rvalue_bit_select_func)(uint64_t);

  // 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_; }

  // 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_; }

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

  int
  reference_flags() const
  { return this->reference_flags_; }

  // Instruction associated with this relocation.
  Reloc_inst
  reloc_inst() const
  { return this->reloc_inst_; }

  // Check overflow of x
  bool checkup_x_value(int64_t x) const
  { return this->rvalue_checkup_func_(x); }

  // Return portions of x as is defined in aarch64-reloc.def.
  uint64_t select_x_value(uint64_t x) const
  { return this->rvalue_bit_select_func_(x); }

 protected:
  // These are protected.  We only allow AArch64_reloc_property_table to
  // manage AArch64_reloc_property.
  AArch64_reloc_property(unsigned int code, const char* name, Reloc_type rtype,
			 Reloc_class rclass,
			 bool is_implemented,
			 int group_index,
			 int reference_flags,
			 Reloc_inst reloc_inst,
			 rvalue_checkup_func_p rvalue_checkup_func,
			 rvalue_bit_select_func rvalue_bit_select);

  friend class AArch64_reloc_property_table;

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

  // Relocation code.
  const unsigned int code_;
  // Relocation name.
  const 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;
  const int reference_flags_;
  // Instruction associated with relocation.
  Reloc_inst reloc_inst_;
  rvalue_checkup_func_p rvalue_checkup_func_;
  rvalue_bit_select_func rvalue_bit_select_func_;
};

class AArch64_reloc_property_table
{
 public:
  AArch64_reloc_property_table();

  const AArch64_reloc_property*
  get_reloc_property(unsigned int code) const
  {
    unsigned int idx = code_to_array_index(code);
    return this->table_[idx];
  }

  // Like get_reloc_property but only return non-NULL if relocation code is
  // static and implemented.
  const AArch64_reloc_property*
  get_implemented_static_reloc_property(unsigned int code) const
  {
    unsigned int idx = code_to_array_index(code);
    const AArch64_reloc_property* arp = this->table_[idx];
    return ((arp != NULL
	     && (arp->reloc_type() == AArch64_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.
  AArch64_reloc_property_table(const AArch64_reloc_property_table&);
  AArch64_reloc_property_table& operator=(const AArch64_reloc_property_table&);

  // Map aarch64 rtypes into range(0,300) as following
  //   256 ~ 313 -> 0 ~ 57
  //   512 ~ 573 -> 128 ~ 189
  int
  code_to_array_index(unsigned int code) const
  {
    if (code == 0) return 0;
    if (!((code >= elfcpp::R_AARCH64_ABS64 &&
	   code <= elfcpp::R_AARCH64_LD64_GOTPAGE_LO15)
	  || (code >= elfcpp::R_AARCH64_TLSGD_ADR_PREL21 &&
	      code <= elfcpp::R_AARCH64_TLSLD_LDST128_DTPREL_LO12_NC)))
      {
	gold_error(_("Invalid/unrecognized reloc reloc %d."), code);
      }
    unsigned int rv = -1;
    if (code & (1 << 9))
      rv = 128 + code - 512;  // 512 - 573
    else if (code & (1 << 8))
      rv = code - 256;  // 256 - 313
    gold_assert(rv <= Property_table_size);
    return rv;
  }

  static const unsigned int Property_table_size = 300;
  AArch64_reloc_property* table_[Property_table_size];
};  // End of class AArch64_reloc_property_table

} // End namespace gold.

#endif // !defined(GOLD_AARCH64_RELOC_PROPERTY_H)
