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

// Copyright (C) 2014-2021 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)
