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

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

#include "gold.h"

#include "aarch64-reloc-property.h"
#include "aarch64.h"

#include "symtab.h"

#include<stdio.h>

namespace gold
{

template<int L, int U>
bool
rvalue_checkup(int64_t x)
{
  // We save the extra_alignment_requirement bits on [31:16] of U.
  // "extra_alignment_requirement" could be 0, 1, 3, 7 and 15.
  unsigned short extra_alignment_requirement = (U & 0xFFFF0000) >> 16;
  // [15:0] of U indicates the upper bound check.
  int64_t u = U & 0x0000FFFF;
  if (u == 0)
    {
      // No requirement to check overflow.
      gold_assert(L == 0);
      return (x & extra_alignment_requirement) == 0;
    }

  // Check both overflow and alignment if needed.
  int64_t low_bound = -(L == 0 ? 0 : ((int64_t)1 << L));
  int64_t up_bound = ((int64_t)1 << u);
  return ((low_bound <= x && x < up_bound)
	  && ((x & extra_alignment_requirement) == 0));
}

template<>
bool
rvalue_checkup<0, 0>(int64_t) { return true; }

template<int L, int U>
uint64_t
rvalue_bit_select(uint64_t x)
{
  if (U == 63) return x >> L;
  return (x & (((uint64_t)1 << (U+1)) - 1)) >> L;
}

template<>
uint64_t
rvalue_bit_select<0, 0>(uint64_t x) { return x; }

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)
  : code_(code), name_(name), reloc_type_(rtype), reloc_class_(rclass),
    group_index_(group_index),
    is_implemented_(is_implemented),
    reference_flags_(reference_flags),
    reloc_inst_(reloc_inst),
    rvalue_checkup_func_(rvalue_checkup_func),
    rvalue_bit_select_func_(rvalue_bit_select)
{}

AArch64_reloc_property_table::AArch64_reloc_property_table()
{
  const bool Y(true), N(false);
  for (unsigned int i = 0; i < Property_table_size; ++i)
    table_[i] = NULL;

#define RL_CHECK_ALIGN2   (1  << 16)
#define RL_CHECK_ALIGN4   (3  << 16)
#define RL_CHECK_ALIGN8   (7  << 16)
#define RL_CHECK_ALIGN16  (15 << 16)

#undef ARD
#define ARD(rname, type, class, is_implemented, group_index, LB, UB, BSL, BSH, RFLAGS, inst) \
    do \
      { \
	int tidx = code_to_array_index(elfcpp::R_AARCH64_##rname); \
	AArch64_reloc_property * p = new AArch64_reloc_property( \
	  elfcpp::R_AARCH64_##rname, "R_AARCH64_" #rname, \
	  AArch64_reloc_property::RT_##type, \
	  AArch64_reloc_property::RC_##class, \
	  is_implemented, \
	  group_index, \
	  (RFLAGS), \
	  AArch64_reloc_property::INST_##inst,	\
	  rvalue_checkup<LB,UB>,    \
	  rvalue_bit_select<BSL,BSH>);		\
	table_[tidx] = p; \
      } \
    while (0);
#include"aarch64-reloc.def"
#undef ARD
}

// Return a string describing a relocation code that fails to get a
// relocation property in get_implemented_static_reloc_property().

std::string
AArch64_reloc_property_table::reloc_name_in_error_message(unsigned int code)
{
  int tidx = code_to_array_index(code);
  const AArch64_reloc_property* arp = this->table_[tidx];

  if (arp == NULL)
    {
      char buffer[100];
      sprintf(buffer, _("invalid reloc %u"), code);
      return std::string(buffer);
    }

  // gold only implements static relocation codes.
  AArch64_reloc_property::Reloc_type reloc_type = arp->reloc_type();
  gold_assert(reloc_type == AArch64_reloc_property::RT_STATIC
	      || !arp->is_implemented());

  const char* prefix = NULL;
  switch (reloc_type)
    {
    case AArch64_reloc_property::RT_STATIC:
      prefix = arp->is_implemented() ? _("reloc ") : _("unimplemented reloc ");
      break;
    case AArch64_reloc_property::RT_DYNAMIC:
      prefix = _("dynamic reloc ");
      break;
    default:
      gold_unreachable();
    }
  return std::string(prefix) + arp->name();
}

}
