/* Infineon XC16X-specific support for 16-bit ELF.
   Copyright 2006, 2007, 2009, 2010  Free Software Foundation, Inc.
   Contributed by KPIT Cummins Infosystems 

   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, 51 Franklin Street - Fifth Floor, Boston,
   MA 02110-1301, USA.  */

#include "sysdep.h"
#include "bfd.h"
#include "libbfd.h"
#include "elf-bfd.h"
#include "elf/xc16x.h"
#include "dwarf2.h"
#include "libiberty.h"

static reloc_howto_type xc16x_elf_howto_table [] =
{
  /* This reloc does nothing.  */
  HOWTO (R_XC16X_NONE,		/* type */
	 0,			/* rightshift */
	 1,			/* size (0 = byte, 1 = short, 2 = long) */
	 16,			/* bitsize */
	 FALSE,			/* pc_relative */
	 0,			/* bitpos */
	 complain_overflow_bitfield, /* complain_on_overflow */
	 bfd_elf_generic_reloc,	/* special_function */
	 "R_XC16X_NONE",	/* name */
	 FALSE,			/* partial_inplace */
	 0,			/* src_mask */
	 0,			/* dst_mask */
	 FALSE),		/* pcrel_offset */

  /* An 8 bit absolute relocation.  */
  HOWTO (R_XC16X_ABS_8,		/* type */
	 0,			/* rightshift */
	 0,			/* size (0 = byte, 1 = short, 2 = long) */
	 8,			/* bitsize */
	 FALSE,			/* pc_relative */
	 8,			/* bitpos */
	 complain_overflow_bitfield, /* complain_on_overflow */
	 bfd_elf_generic_reloc,	/* special_function */
	 "R_XC16X_ABS_8",	/* name */
	 TRUE,			/* partial_inplace */
	 0x0000,		/* src_mask */
	 0x00ff,		/* dst_mask */
	 FALSE),		/* pcrel_offset */

  /* A 16 bit absolute relocation.  */
  HOWTO (R_XC16X_ABS_16,	/* type */
	 0,			/* rightshift */
	 1,			/* size (0 = byte, 1 = short, 2 = long) */
	 16,			/* bitsize */
	 FALSE,			/* pc_relative */
	 0,			/* bitpos */
	 complain_overflow_dont, /* complain_on_overflow */
	 bfd_elf_generic_reloc,	/* special_function */
	 "R_XC16X_ABS_16",	/* name */
	 TRUE,			/* partial_inplace */
	 0x00000000,		/* src_mask */
	 0x0000ffff,		/* dst_mask */
	 FALSE),		/* pcrel_offset */

  HOWTO (R_XC16X_ABS_32,	/* type */
  	 0,			/* rightshift */
  	 2,			/* size (0 = byte, 1 = short, 2 = long) */
  	 32,			/* bitsize */
  	 FALSE,			/* pc_relative */
  	 0,			/* bitpos */
  	 complain_overflow_bitfield, /* complain_on_overflow */
  	 bfd_elf_generic_reloc,	/* special_function */
  	 "R_XC16X_ABS_32",	/* name */
  	 TRUE,			/* partial_inplace */
  	 0x00000000,		/* src_mask */
  	 0xffffffff,		/* dst_mask */
  	 FALSE),		/* pcrel_offset */


  /* A PC relative 8 bit relocation.  */
  HOWTO (R_XC16X_8_PCREL,	/* type */
	 0,			/* rightshift */
	 0,			/* size (0 = byte, 1 = short, 2 = long) */
	 8,			/* bitsize */
	 TRUE,			/* pc_relative */
	 8,			/* bitpos */
	 complain_overflow_signed, /* complain_on_overflow */
	 bfd_elf_generic_reloc, /* special_function */
	 "R_XC16X_8_PCREL",	/* name */
	 FALSE,			/* partial_inplace */
	 0x0000,		/* src_mask */
	 0x00ff,		/* dst_mask */
	 TRUE),		/* pcrel_offset */

  /* Relocation regarding page number.  */
    HOWTO (R_XC16X_PAG,	/* type */
  	 0,			/* rightshift */
  	 1,			/* size (0 = byte, 1 = short, 2 = long) */
  	 16,			/* bitsize */
  	 FALSE,			/* pc_relative */
  	 0,			/* bitpos */
  	 complain_overflow_signed, /* complain_on_overflow */
  	 bfd_elf_generic_reloc, /* special_function */
  	 "R_XC16X_PAG",	/* name */
  	 TRUE,			/* partial_inplace */
  	 0x00000000,		/* src_mask */
  	 0x0000ffff,		/* dst_mask */
  	 FALSE),		/* pcrel_offset */


  /* Relocation regarding page number.  */
      HOWTO (R_XC16X_POF,	/* type */
    	 0,			/* rightshift */
    	 1,			/* size (0 = byte, 1 = short, 2 = long) */
    	 16,			/* bitsize */
    	 FALSE,			/* pc_relative */
    	 0,			/* bitpos  */
    	 complain_overflow_signed, /* complain_on_overflow  */
    	 bfd_elf_generic_reloc, /* special_function  */
    	 "R_XC16X_POF",	/* name  */
    	 TRUE,			/* partial_inplace  */
    	 0x00000000,		/* src_mask  */
    	 0x0000ffff,		/* dst_mask  */
    	 FALSE),		/* pcrel_offset  */


  /* Relocation regarding segment number.   */
      HOWTO (R_XC16X_SEG,	/* type  */
    	 0,			/* rightshift  */
    	 1,			/* size (0 = byte, 1 = short, 2 = long)  */
    	 16,			/* bitsize  */
    	 FALSE,			/* pc_relative  */
    	 0,			/* bitpos  */
    	 complain_overflow_signed, /* complain_on_overflow  */
    	 bfd_elf_generic_reloc, /* special_function  */
    	 "R_XC16X_SEG",	/* name  */
    	 TRUE,			/* partial_inplace  */
    	 0x00000000,		/* src_mask  */
    	 0x0000ffff,		/* dst_mask  */
    	 FALSE),		/* pcrel_offset  */

  /* Relocation regarding segment offset.  */
      HOWTO (R_XC16X_SOF,	/* type  */
    	 0,			/* rightshift  */
    	 1,			/* size (0 = byte, 1 = short, 2 = long)  */
    	 16,			/* bitsize  */
    	 FALSE,			/* pc_relative  */
    	 0,			/* bitpos  */
    	 complain_overflow_signed, /* complain_on_overflow  */
    	 bfd_elf_generic_reloc, /* special_function  */
    	 "R_XC16X_SOF",	/* name */
    	 TRUE,			/* partial_inplace  */
    	 0x00000000,		/* src_mask  */
    	 0x0000ffff,		/* dst_mask  */
    	 FALSE)			/* pcrel_offset  */
};


/* Map BFD reloc types to XC16X ELF reloc types.  */

struct xc16x_reloc_map
{
  bfd_reloc_code_real_type bfd_reloc_val;
  unsigned int xc16x_reloc_val;
};

static const struct xc16x_reloc_map xc16x_reloc_map [] =
{
  { BFD_RELOC_NONE,           R_XC16X_NONE },
  { BFD_RELOC_8,              R_XC16X_ABS_8 },
  { BFD_RELOC_16,             R_XC16X_ABS_16 },
  { BFD_RELOC_32,             R_XC16X_ABS_32 },
  { BFD_RELOC_8_PCREL,        R_XC16X_8_PCREL },
  { BFD_RELOC_XC16X_PAG,      R_XC16X_PAG},
  { BFD_RELOC_XC16X_POF,      R_XC16X_POF},
  { BFD_RELOC_XC16X_SEG,      R_XC16X_SEG},
  { BFD_RELOC_XC16X_SOF,      R_XC16X_SOF},
};


/* This function is used to search for correct relocation type from
   howto structure.  */

static reloc_howto_type *
xc16x_reloc_type_lookup (bfd *abfd ATTRIBUTE_UNUSED,
			 bfd_reloc_code_real_type code)
{
  unsigned int i;

  for (i = ARRAY_SIZE (xc16x_reloc_map); --i;)
    if (xc16x_reloc_map [i].bfd_reloc_val == code)
      return & xc16x_elf_howto_table [xc16x_reloc_map[i].xc16x_reloc_val];

  return NULL;
}

static reloc_howto_type *
xc16x_reloc_name_lookup (bfd *abfd ATTRIBUTE_UNUSED,
			 const char *r_name)
{
  unsigned int i;

  for (i = 0;
       i < sizeof (xc16x_elf_howto_table) / sizeof (xc16x_elf_howto_table[0]);
       i++)
    if (xc16x_elf_howto_table[i].name != NULL
	&& strcasecmp (xc16x_elf_howto_table[i].name, r_name) == 0)
      return &xc16x_elf_howto_table[i];

  return NULL;
}

/* For a particular operand this function is
   called to finalise the type of relocation.  */

static void
elf32_xc16x_info_to_howto (bfd *abfd ATTRIBUTE_UNUSED, arelent *bfd_reloc,
			   Elf_Internal_Rela *elf_reloc)
{
  unsigned int r;
  unsigned int i;

  r = ELF32_R_TYPE (elf_reloc->r_info);
  for (i = 0; i < ARRAY_SIZE (xc16x_elf_howto_table); i++)
    if (xc16x_elf_howto_table[i].type == r)
      {
	bfd_reloc->howto = &xc16x_elf_howto_table[i];
	return;
      }
  abort ();
}

static bfd_reloc_status_type
elf32_xc16x_final_link_relocate (unsigned long r_type,
				 bfd *input_bfd,
				 bfd *output_bfd ATTRIBUTE_UNUSED,
				 asection *input_section ATTRIBUTE_UNUSED,
				 bfd_byte *contents,
				 bfd_vma offset,
				 bfd_vma value,
				 bfd_vma addend,
				 struct bfd_link_info *info ATTRIBUTE_UNUSED,
				 asection *sym_sec ATTRIBUTE_UNUSED,
				 int is_local ATTRIBUTE_UNUSED)
{
  bfd_byte *hit_data = contents + offset;
  bfd_vma val1;

  switch (r_type)
    {
    case R_XC16X_NONE:
      return bfd_reloc_ok;

    case R_XC16X_ABS_16:
      value += addend;
      bfd_put_16 (input_bfd, value, hit_data);
      return bfd_reloc_ok;

    case R_XC16X_8_PCREL:
      bfd_put_8 (input_bfd, value, hit_data);
      return bfd_reloc_ok;

      /* Following case is to find page number from actual
	 address for this divide value by 16k i.e. page size.  */

    case R_XC16X_PAG:
      value += addend;
      value /= 0x4000;
      bfd_put_16 (input_bfd, value, hit_data);
      return bfd_reloc_ok;

      /* Following case is to find page offset from actual address
	 for this take modulo of value by 16k i.e. page size.  */

    case R_XC16X_POF:
      value += addend;
      value %= 0x4000;
      bfd_put_16 (input_bfd, value, hit_data);
      return bfd_reloc_ok;

      /* Following case is to find segment number from actual
	 address for this divide value by 64k i.e. segment size.  */

    case R_XC16X_SEG:
      value += addend;
      value /= 0x10000;
      bfd_put_16 (input_bfd, value, hit_data);
      return bfd_reloc_ok;

      /* Following case is to find segment offset from actual address
	 for this take modulo of value by 64k i.e. segment size.  */

    case R_XC16X_SOF:
      value += addend;
      value %= 0x10000;
      bfd_put_16 (input_bfd, value, hit_data);
      return bfd_reloc_ok;

    case R_XC16X_ABS_32:
      if (!strstr (input_section->name,".debug"))
	{
	  value += addend;
	  val1 = value;
	  value %= 0x4000;
	  val1 /= 0x4000;
	  val1 = val1 << 16;
	  value += val1;
	  bfd_put_32 (input_bfd, value, hit_data);
	}
      else
	{
	  value += addend;
	  bfd_put_32 (input_bfd, value, hit_data);
	}
      return bfd_reloc_ok;

    default:
      return bfd_reloc_notsupported;
    }
}

static bfd_boolean
elf32_xc16x_relocate_section (bfd *output_bfd,
			      struct bfd_link_info *info,
			      bfd *input_bfd,
			      asection *input_section,
			      bfd_byte *contents,
			      Elf_Internal_Rela *relocs,
			      Elf_Internal_Sym *local_syms,
			      asection **local_sections)
{
  Elf_Internal_Shdr *symtab_hdr;
  struct elf_link_hash_entry **sym_hashes;
  Elf_Internal_Rela *rel, *relend;

  symtab_hdr = &elf_tdata (input_bfd)->symtab_hdr;
  sym_hashes = elf_sym_hashes (input_bfd);

  rel = relocs;
  relend = relocs + input_section->reloc_count;
  for (; rel < relend; rel++)
    {
      unsigned int r_type;
      unsigned long r_symndx;
      Elf_Internal_Sym *sym;
      asection *sec;
      struct elf_link_hash_entry *h;
      bfd_vma relocation;

      /* This is a final link.  */
      r_symndx = ELF32_R_SYM (rel->r_info);
      r_type = ELF32_R_TYPE (rel->r_info);
      h = NULL;
      sym = NULL;
      sec = NULL;
      if (r_symndx < symtab_hdr->sh_info)
	{
	  sym = local_syms + r_symndx;
	  sec = local_sections[r_symndx];
	  relocation = _bfd_elf_rela_local_sym (output_bfd, sym, &sec, rel);
	}
      else
	{
	  bfd_boolean unresolved_reloc, warned;

	  RELOC_FOR_GLOBAL_SYMBOL (info, input_bfd, input_section, rel,
				   r_symndx, symtab_hdr, sym_hashes,
				   h, sec, relocation,
				   unresolved_reloc, warned);
	}

      if (sec != NULL && elf_discarded_section (sec))
	{
	  /* For relocs against symbols from removed linkonce sections,
	     or sections discarded by a linker script, we just want the
	     section contents cleared.  Avoid any special processing.  */
	  reloc_howto_type *howto;
	  howto = xc16x_reloc_type_lookup (input_bfd, r_type);
	  RELOC_AGAINST_DISCARDED_SECTION (info, input_bfd, input_section,
					   rel, relend, howto, contents);
	}

      if (info->relocatable)
	continue;

      elf32_xc16x_final_link_relocate (r_type, input_bfd, output_bfd,
				       input_section,
				       contents, rel->r_offset,
				       relocation, rel->r_addend,
				       info, sec, h == NULL);
    }

  return TRUE;
}


static void
elf32_xc16x_final_write_processing (bfd *abfd,
				    bfd_boolean linker ATTRIBUTE_UNUSED)
{
  unsigned long val;

  switch (bfd_get_mach (abfd))
    {
    default:
    case bfd_mach_xc16x:
      val = 0x1000;
      break;

    case bfd_mach_xc16xl:
      val = 0x1001;
      break;

    case bfd_mach_xc16xs:
      val = 0x1002;
      break;
    }

  elf_elfheader (abfd)->e_flags |= val;
}

static unsigned long
elf32_xc16x_mach (flagword flags)
{  
  switch (flags)
    {
    case 0x1000:
    default: 
      return bfd_mach_xc16x;

    case 0x1001:
      return bfd_mach_xc16xl;

    case 0x1002:
      return bfd_mach_xc16xs;
    }
}


static bfd_boolean
elf32_xc16x_object_p (bfd *abfd)
{
  bfd_default_set_arch_mach (abfd, bfd_arch_xc16x,
			     elf32_xc16x_mach (elf_elfheader (abfd)->e_flags));
  return TRUE;
}


#define ELF_ARCH		bfd_arch_xc16x
#define ELF_MACHINE_CODE	EM_XC16X
#define ELF_MAXPAGESIZE		0x100

#define TARGET_LITTLE_SYM       bfd_elf32_xc16x_vec
#define TARGET_LITTLE_NAME	"elf32-xc16x"
#define elf_backend_final_write_processing	elf32_xc16x_final_write_processing
#define elf_backend_object_p   		elf32_xc16x_object_p
#define elf_backend_can_gc_sections	1
#define bfd_elf32_bfd_reloc_type_lookup	xc16x_reloc_type_lookup
#define bfd_elf32_bfd_reloc_name_lookup xc16x_reloc_name_lookup
#define elf_info_to_howto		elf32_xc16x_info_to_howto
#define elf_info_to_howto_rel		elf32_xc16x_info_to_howto
#define elf_backend_relocate_section  	elf32_xc16x_relocate_section
#define elf_backend_rela_normal		1

#include "elf32-target.h"
