/* ARC-specific support for 32-bit ELF
   Copyright (C) 1994-2016 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

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 == FALSE)
	{
	  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,
			    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 == FALSE)
    {
      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 == FALSE)
    {
       /* 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 */
