/* Infineon XC16X-specific support for 16-bit ELF.
   Copyright 2006, 2007  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 "elf/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;
      bfd_reloc_status_type r;

      /* 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 zeroed.  Avoid any special processing.  */
	  reloc_howto_type *howto;
	  howto = xc16x_reloc_type_lookup (input_bfd, r_type);
	  _bfd_clear_contents (howto, input_bfd, contents + rel->r_offset);
	  rel->r_info = 0;
	  rel->r_addend = 0;
	  continue;
	}

      if (info->relocatable)
	continue;

      r = 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"
