/* ARC-specific support for 32-bit ELF
   Copyright (C) 1994-2017 Free Software Foundation, Inc.
   Contributed by Cupertino Miranda (cmiranda@synopsys.com).

   This file is part of BFD, the Binary File Descriptor library.

   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 ARC_GOT_H
#define ARC_GOT_H

#define TCB_SIZE (8)

enum tls_type_e
{
  GOT_UNKNOWN = 0,
  GOT_NORMAL,
  GOT_TLS_GD,
  GOT_TLS_IE,
  GOT_TLS_LE
};

enum tls_got_entries
{
  TLS_GOT_NONE = 0,
  TLS_GOT_MOD,
  TLS_GOT_OFF,
  TLS_GOT_MOD_AND_OFF
};

struct got_entry
{
  struct got_entry *next;
  enum tls_type_e type;
  bfd_vma offset;
  bfd_boolean processed;
  bfd_boolean created_dyn_relocation;
  enum tls_got_entries existing_entries;
};

static struct got_entry **
arc_get_local_got_ents (bfd * abfd)
{
  static struct got_entry **local_got_ents = NULL;

  if (local_got_ents == NULL)
    {
      size_t	   size;
      Elf_Internal_Shdr *symtab_hdr = &((elf_tdata (abfd))->symtab_hdr);

      size = symtab_hdr->sh_info * sizeof (bfd_vma);
      local_got_ents = (struct got_entry **)
	bfd_alloc (abfd, sizeof (struct got_entry *) * size);
      if (local_got_ents == NULL)
	return FALSE;

      memset (local_got_ents, 0, sizeof (struct got_entry *) * size);
      elf_local_got_ents (abfd) = local_got_ents;
    }

  return local_got_ents;
}

static struct got_entry *
got_entry_for_type (struct got_entry **list,
		    enum tls_type_e type)
{
  struct got_entry **p = list;

  while (*p != NULL)
    {
      if ((*p)->type == type)
	return *p;
      p = &((*p)->next);
    }
  return NULL;
}

static void
new_got_entry_to_list (struct got_entry **list,
		       enum tls_type_e type,
		       bfd_vma offset,
		       enum tls_got_entries existing_entries)
{
  /* Find list end.  Avoid having multiple entries of the same
     type.  */
  struct got_entry **p = list;
  struct got_entry *entry;

  while (*p != NULL)
    {
      if ((*p)->type == type)
	return;
      p = &((*p)->next);
    }

  entry = (struct got_entry *) xmalloc (sizeof (struct got_entry));

  entry->type = type;
  entry->offset = offset;
  entry->next = NULL;
  entry->processed = FALSE;
  entry->created_dyn_relocation = FALSE;
  entry->existing_entries = existing_entries;

  ARC_DEBUG ("New GOT got entry added to list: "
	     "type: %d, offset: %ld, existing_entries: %d\n",
	     type, (long) offset, existing_entries);

  /* Add the entry to the end of the list.  */
  *p = entry;
}

static enum tls_type_e
tls_type_for_reloc (reloc_howto_type *howto)
{
  enum tls_type_e ret = GOT_UNKNOWN;

  if (is_reloc_for_GOT (howto))
    return GOT_NORMAL;

  switch (howto->type)
    {
    case R_ARC_TLS_GD_GOT:
      ret = GOT_TLS_GD;
      break;
    case R_ARC_TLS_IE_GOT:
      ret = GOT_TLS_IE;
      break;
    case R_ARC_TLS_LE_32:
      ret = GOT_TLS_LE;
      break;
    default:
      ret = GOT_UNKNOWN;
      break;
    }

  return ret;
};

static struct got_entry **
get_got_entry_list_for_symbol (bfd *abfd,
			       unsigned long r_symndx,
			       struct elf_link_hash_entry *h)
{
  if (h != NULL)
    {
      return &h->got.glist;
    }
  else
    {
      struct got_entry **local_got_ents
	= arc_get_local_got_ents (abfd);
      return &local_got_ents[r_symndx];
    }
}


static enum tls_type_e
arc_got_entry_type_for_reloc (reloc_howto_type *howto)
{
  enum tls_type_e type = GOT_UNKNOWN;

  if (is_reloc_for_GOT (howto))
    return  GOT_NORMAL;

  if (is_reloc_for_TLS (howto))
    {
      switch (howto->type)
	{
	  case R_ARC_TLS_GD_GOT:
	    type = GOT_TLS_GD;
	    break;
	  case R_ARC_TLS_IE_GOT:
	    type = GOT_TLS_IE;
	    break;
	  default:
	    break;
	}
    }
  return type;
}

#define ADD_SYMBOL_REF_SEC_AND_RELOC(SECNAME, COND_FOR_RELOC, H)	\
  htab->s##SECNAME->size;						\
  {									\
    if (COND_FOR_RELOC)							\
      {									\
	htab->srel##SECNAME->size += sizeof (Elf32_External_Rela);	\
	  ARC_DEBUG ("arc_info: Added reloc space in "			\
		     #SECNAME " section at " __FILE__			\
		     ":%d for symbol %s\n",				\
		     __LINE__, name_for_global_symbol (H));		\
      }									\
    if (H)								\
      if (h->dynindx == -1 && !h->forced_local)				\
	if (! bfd_elf_link_record_dynamic_symbol (info, H))		\
	  return FALSE;							\
     htab->s##SECNAME->size += 4;					\
   }									\

static bfd_boolean
arc_fill_got_info_for_reloc (enum tls_type_e type,
			     struct got_entry **list,
			     struct bfd_link_info *  info,
			     struct elf_link_hash_entry *h)
{
  struct elf_link_hash_table *htab = elf_hash_table (info);

  if (got_entry_for_type (list, type) != NULL)
    return TRUE;

  switch (type)
    {
      case GOT_NORMAL:
	{
  	  bfd_vma offset
	    = ADD_SYMBOL_REF_SEC_AND_RELOC (got, bfd_link_pic (info)
						 || h != NULL, h);
  	  new_got_entry_to_list (list, type, offset, TLS_GOT_NONE);
	}
	break;


      case GOT_TLS_GD:
	{
	  bfd_vma offset
	    = ADD_SYMBOL_REF_SEC_AND_RELOC (got, TRUE, h);
	  bfd_vma ATTRIBUTE_UNUSED notneeded
	    = ADD_SYMBOL_REF_SEC_AND_RELOC (got, TRUE, h);
	  new_got_entry_to_list (list, type, offset, TLS_GOT_MOD_AND_OFF);
	}
	break;
      case GOT_TLS_IE:
      case GOT_TLS_LE:
	{
	  bfd_vma offset
	    = ADD_SYMBOL_REF_SEC_AND_RELOC (got, TRUE, h);
	  new_got_entry_to_list (list, type, offset, TLS_GOT_OFF);
	}
	break;

      default:
	return FALSE;
	break;
    }
  return TRUE;
}


static bfd_vma
relocate_fix_got_relocs_for_got_info (struct got_entry **          list_p,
				      enum tls_type_e              type,
				      struct bfd_link_info *       info,
				      bfd *                        output_bfd,
				      unsigned long                r_symndx,
				      Elf_Internal_Sym *           local_syms,
			  	      asection **                  local_sections,
			     	      struct elf_link_hash_entry * h,
				      struct arc_relocation_data * reloc_data)
{
  struct elf_link_hash_table *htab = elf_hash_table (info);
  struct got_entry *entry = NULL;

  if (list_p == NULL || type == GOT_UNKNOWN || type == GOT_TLS_LE)
    return 0;

  entry = got_entry_for_type (list_p, type);
  BFD_ASSERT (entry);

  if (h == NULL
      || (! elf_hash_table (info)->dynamic_sections_created
	  || (bfd_link_pic (info)
	      && SYMBOL_REFERENCES_LOCAL (info, h))))
    {
      const char ATTRIBUTE_UNUSED *symbol_name;
      static const char local_name[] = "(local)";
      asection *tls_sec = NULL;
      bfd_vma sym_value = 0;

      if (h != NULL)
	{
	  // TODO: This should not be here.
	  reloc_data->sym_value = h->root.u.def.value;
	  reloc_data->sym_section = h->root.u.def.section;

	  sym_value = h->root.u.def.value
	    + h->root.u.def.section->output_section->vma
	    + h->root.u.def.section->output_offset;

	  tls_sec = elf_hash_table (info)->tls_sec;

	  symbol_name = h->root.root.string;
	}
      else
	{
	  Elf_Internal_Sym *sym = local_syms + r_symndx;
	  asection *sec = local_sections[r_symndx];

	  sym_value = sym->st_value
	    + sec->output_section->vma
	    + sec->output_offset;

	  tls_sec = elf_hash_table (info)->tls_sec;

	  symbol_name = local_name;
	}


      if (entry && !entry->processed)
	{
	  switch (entry->type)
	    {
	    case GOT_TLS_GD:
	      {
		BFD_ASSERT (tls_sec && tls_sec->output_section);
		bfd_vma sec_vma = tls_sec->output_section->vma;

		bfd_put_32 (output_bfd,
			    sym_value - sec_vma,
			    htab->sgot->contents + entry->offset
			    + (entry->existing_entries == TLS_GOT_MOD_AND_OFF
			       ? 4 : 0));

		ARC_DEBUG ("arc_info: FIXED -> %s value = %#lx "
			   "@ %lx, for symbol %s\n",
			   (entry->type == GOT_TLS_GD ? "GOT_TLS_GD" :
			    "GOT_TLS_IE"),
			   (long) (sym_value - sec_vma),
			   (long) (htab->sgot->output_section->vma
			      + htab->sgot->output_offset->vma
			      + entry->offset
			      + (entry->existing_entries == TLS_GOT_MOD_AND_OFF
				 ? 4 : 0)),
			   symbol_name);
	      }
	      break;

	    case GOT_TLS_IE:
	      {
		BFD_ASSERT (tls_sec && tls_sec->output_section);
		bfd_vma ATTRIBUTE_UNUSED sec_vma
		  = tls_sec->output_section->vma;

		bfd_put_32 (output_bfd,
			    sym_value - sec_vma
			    + (elf_hash_table (info)->dynamic_sections_created ? 0 : TCB_SIZE),
			    htab->sgot->contents + entry->offset
			    + (entry->existing_entries == TLS_GOT_MOD_AND_OFF
			       ? 4 : 0));

		ARC_DEBUG ("arc_info: FIXED -> %s value = %#lx "
			   "@ %p, for symbol %s\n",
			   (entry->type == GOT_TLS_GD ? "GOT_TLS_GD" :
			    "GOT_TLS_IE"),
			   (long) (sym_value - sec_vma),
			   (long) (htab->sgot->output_section->vma
			      + htab->sgot->output_offset->vma
			      + entry->offset
			      + (entry->existing_entries == TLS_GOT_MOD_AND_OFF
				 ? 4 : 0)),
			   symbol_name);
	      }
	      break;

	    case GOT_NORMAL:
	      {
		bfd_vma sec_vma
		  = reloc_data->sym_section->output_section->vma
		  + reloc_data->sym_section->output_offset;

		if (h != NULL
		    && h->root.type == bfd_link_hash_undefweak)
		  ARC_DEBUG ("arc_info: PATCHED: NOT_PATCHED "
			     "@ %#08lx for sym %s in got offset %#lx "
			     "(is undefweak)\n",
			     (long) (htab->sgot->output_section->vma
				     + htab->sgot->output_offset
				     + entry->offset),
			     symbol_name,
			     (long) entry->offset);
		else
		  {
		    bfd_put_32 (output_bfd,
				reloc_data->sym_value + sec_vma,
				htab->sgot->contents + entry->offset);
		    ARC_DEBUG ("arc_info: PATCHED: %#08lx "
			       "@ %#08lx for sym %s in got offset %#lx\n",
			       (long) (reloc_data->sym_value + sec_vma),
			       (long) (htab->sgot->output_section->vma
				       + htab->sgot->output_offset + entry->offset),
			       symbol_name,
			       (long) entry->offset);
		  }
	      }
	      break;
	    default:
	      BFD_ASSERT (0);
	      break;
	    }
	  entry->processed = TRUE;
	}
    }

  return entry->offset;
}

static void
create_got_dynrelocs_for_single_entry (struct got_entry *list,
				       bfd *output_bfd,
				       struct bfd_link_info *  info,
				       struct elf_link_hash_entry *h)
{
  if (list == NULL)
    return;

  bfd_vma got_offset = list->offset;

  if (list->type == GOT_NORMAL
      && !list->created_dyn_relocation)
    {
      if (bfd_link_pic (info)
	  && h != NULL
	      && (info->symbolic || h->dynindx == -1)
	      && h->def_regular)
	{
	  ADD_RELA (output_bfd, got, got_offset, 0, R_ARC_RELATIVE, 0);
	}
      /* Do not fully understand the side effects of this condition.
	 The relocation space might still being reserved.  Perhaps
	 I should clear its value.  */
      else if (h != NULL && h->dynindx != -1)
	{
	  ADD_RELA (output_bfd, got, got_offset, h->dynindx, R_ARC_GLOB_DAT, 0);
	}
      list->created_dyn_relocation = TRUE;
    }
  else if (list->existing_entries != TLS_GOT_NONE
	   && !list->created_dyn_relocation)
    {
       /* TODO TLS: This is not called for local symbols.
	  In order to correctly implement TLS, this should also
	  be called for all local symbols with tls got entries.
	  Should be moved to relocate_section in order to make it
	  work for local symbols.  */
      struct elf_link_hash_table *htab = elf_hash_table (info);
      enum tls_got_entries e = list->existing_entries;

      BFD_ASSERT (list->type != GOT_TLS_GD
    	      || list->existing_entries == TLS_GOT_MOD_AND_OFF);

      bfd_vma dynindx = (h == NULL || h->dynindx == -1) ? 0 : h->dynindx;

      if (e == TLS_GOT_MOD_AND_OFF || e == TLS_GOT_MOD)
	{
	      ADD_RELA (output_bfd, got, got_offset, dynindx,
	    	    R_ARC_TLS_DTPMOD, 0);
	      ARC_DEBUG ("arc_info: TLS_DYNRELOC: type = %d, \
GOT_OFFSET = %#lx, GOT_VMA = %#lx, INDEX = %ld, ADDEND = 0x0\n",
			 list->type,
			 (long) got_offset,
			 (long) (htab->sgot->output_section->vma
				 + htab->sgot->output_offset + got_offset),
			 (long) dynindx);
	}

      if (e == TLS_GOT_MOD_AND_OFF || e == TLS_GOT_OFF)
	{
	  bfd_vma addend = 0;
	  if (list->type == GOT_TLS_IE)
	  {
	    addend = bfd_get_32 (output_bfd,
				 htab->sgot->contents + got_offset);
	  }

	  ADD_RELA (output_bfd, got,
		    got_offset + (e == TLS_GOT_MOD_AND_OFF ? 4 : 0),
		    dynindx,
		    (list->type == GOT_TLS_IE ? R_ARC_TLS_TPOFF
					      : R_ARC_TLS_DTPOFF),
		    addend);

	  ARC_DEBUG ("arc_info: TLS_DYNRELOC: type = %d, \
GOT_OFFSET = %#lx, GOT_VMA = %#lx, INDEX = %ld, ADDEND = %#lx\n",
		     list->type,
		     (long) got_offset,
		     (long) (htab->sgot->output_section->vma
			     + htab->sgot->output_offset + got_offset),
		     (long) dynindx, (long) addend);
	}
      list->created_dyn_relocation = TRUE;
    }
}

static void
create_got_dynrelocs_for_got_info (struct got_entry **list_p,
				   bfd *output_bfd,
				   struct bfd_link_info *  info,
			     	   struct elf_link_hash_entry *h)
{
  if (list_p == NULL)
    return;

  struct got_entry *list = *list_p;
  /* Traverse the list of got entries for this symbol.  */
  while (list)
    {
      create_got_dynrelocs_for_single_entry (list, output_bfd, info, h);
      list = list->next;
    }
}

#undef ADD_SYMBOL_REF_SEC_AND_RELOC

#endif /* ARC_GOT_H */
