/* BFD back-end for Intel 960 COFF files.
   Copyright 1990, 1991, 1992, 1993, 1994, 1995, 1997, 1999, 2000, 2001,
   2002, 2003, 2004, 2007, 2008  Free Software Foundation, Inc.
   Written by Cygnus Support.

   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.  */

#define I960 1
#define BADMAG(x) I960BADMAG(x)

#include "sysdep.h"
#include "bfd.h"
#include "libbfd.h"
#include "coff/i960.h"
#include "coff/internal.h"

#ifndef bfd_pe_print_pdata
#define bfd_pe_print_pdata	NULL
#endif

#include "libcoff.h"		/* To allow easier abstraction-breaking.  */

static bfd_boolean coff_i960_is_local_label_name
  PARAMS ((bfd *, const char *));
static bfd_reloc_status_type optcall_callback
  PARAMS ((bfd *, arelent *, asymbol *, PTR, asection *, bfd *, char **));
static bfd_reloc_status_type coff_i960_relocate
  PARAMS ((bfd *, arelent *, asymbol *, PTR, asection *, bfd *, char **));
static reloc_howto_type *coff_i960_reloc_type_lookup
  PARAMS ((bfd *, bfd_reloc_code_real_type));
static bfd_boolean coff_i960_start_final_link
  PARAMS ((bfd *, struct bfd_link_info *));
static bfd_boolean coff_i960_relocate_section
  PARAMS ((bfd *, struct bfd_link_info *, bfd *, asection *, bfd_byte *,
	   struct internal_reloc *, struct internal_syment *, asection **));
static bfd_boolean coff_i960_adjust_symndx
  PARAMS ((bfd *, struct bfd_link_info *, bfd *, asection *,
	   struct internal_reloc *, bfd_boolean *));

#define COFF_DEFAULT_SECTION_ALIGNMENT_POWER (3)
#define COFF_ALIGN_IN_SECTION_HEADER 1

#define GET_SCNHDR_ALIGN H_GET_32
#define PUT_SCNHDR_ALIGN H_PUT_32

/* The i960 does not support an MMU, so COFF_PAGE_SIZE can be
   arbitrarily small.  */
#define COFF_PAGE_SIZE 1

#define COFF_LONG_FILENAMES

/* This set of local label names is taken from gas.  */

static bfd_boolean
coff_i960_is_local_label_name (abfd, name)
     bfd *abfd ATTRIBUTE_UNUSED;
     const char *name;
{
  return (name[0] == 'L'
	  || (name[0] == '.'
	      && (name[1] == 'C'
		  || name[1] == 'I'
		  || name[1] == '.')));
}

/* This is just like the usual CALC_ADDEND, but it includes the
   section VMA for PC relative relocs.  */
#ifndef CALC_ADDEND
#define CALC_ADDEND(abfd, ptr, reloc, cache_ptr)                \
  {                                                             \
    coff_symbol_type *coffsym = (coff_symbol_type *) NULL;      \
    if (ptr && bfd_asymbol_bfd (ptr) != abfd)                   \
      coffsym = (obj_symbols (abfd)                             \
                 + (cache_ptr->sym_ptr_ptr - symbols));         \
    else if (ptr)                                               \
      coffsym = coff_symbol_from (abfd, ptr);                   \
    if (coffsym != (coff_symbol_type *) NULL                    \
        && coffsym->native->u.syment.n_scnum == 0)              \
      cache_ptr->addend = 0;                                    \
    else if (ptr && bfd_asymbol_bfd (ptr) == abfd               \
             && ptr->section != (asection *) NULL)              \
      cache_ptr->addend = - (ptr->section->vma + ptr->value);   \
    else                                                        \
      cache_ptr->addend = 0;                                    \
    if (ptr && (reloc.r_type == 25 || reloc.r_type == 27))	\
      cache_ptr->addend += asect->vma;				\
  }
#endif

#define CALLS	 0x66003800	/* Template for 'calls' instruction	*/
#define BAL	 0x0b000000	/* Template for 'bal' instruction	*/
#define BAL_MASK 0x00ffffff

static bfd_reloc_status_type
optcall_callback (abfd, reloc_entry, symbol_in, data,
		  input_section, ignore_bfd, error_message)
     bfd *abfd;
     arelent *reloc_entry;
     asymbol *symbol_in;
     PTR data;
     asection *input_section;
     bfd *ignore_bfd ATTRIBUTE_UNUSED;
     char **error_message;
{
  /* This item has already been relocated correctly, but we may be
   * able to patch in yet better code - done by digging out the
   * correct info on this symbol */
  bfd_reloc_status_type result;
  coff_symbol_type *cs = coffsymbol(symbol_in);

  /* Don't do anything with symbols which aren't tied up yet,
     except move the reloc.  */
  if (bfd_is_und_section (cs->symbol.section)) {
    reloc_entry->address += input_section->output_offset;
    return bfd_reloc_ok;
  }

  /* So the target symbol has to be of coff type, and the symbol
     has to have the correct native information within it */
  if ((bfd_asymbol_flavour(&cs->symbol) != bfd_target_coff_flavour)
      || (cs->native == (combined_entry_type *)NULL))
    {
      /* This is interesting, consider the case where we're outputting coff
	 from a mix n match input, linking from coff to a symbol defined in a
	 bout file will cause this match to be true. Should I complain?  This
	 will only work if the bout symbol is non leaf.  */
      *error_message =
	(char *) _("uncertain calling convention for non-COFF symbol");
      result = bfd_reloc_dangerous;
    }
  else
    {
    switch (cs->native->u.syment.n_sclass)
      {
      case C_LEAFSTAT:
      case C_LEAFEXT:
  	/* This is a call to a leaf procedure, replace instruction with a bal
	   to the correct location.  */
	{
	  union internal_auxent *aux = &((cs->native+2)->u.auxent);
	  int word = bfd_get_32 (abfd, (bfd_byte *)data + reloc_entry->address);
	  int olf = (aux->x_bal.x_balntry - cs->native->u.syment.n_value);
	  BFD_ASSERT(cs->native->u.syment.n_numaux==2);

	  /* We replace the original call instruction with a bal to
	     the bal entry point - the offset of which is described in
	     the 2nd auxent of the original symbol. We keep the native
	     sym and auxents untouched, so the delta between the two
	     is the offset of the bal entry point.  */
	  word = ((word +  olf)  & BAL_MASK) | BAL;
  	  bfd_put_32 (abfd, (bfd_vma) word,
		      (bfd_byte *) data + reloc_entry->address);
  	}
	result = bfd_reloc_ok;
	break;
      case C_SCALL:
	/* This is a call to a system call, replace with a calls to # */
	BFD_ASSERT(0);
	result = bfd_reloc_ok;
	break;
      default:
	result = bfd_reloc_ok;
	break;
      }
  }
  return result;
}

/* i960 COFF is used by VxWorks 5.1.  However, VxWorks 5.1 does not
   appear to correctly handle a reloc against a symbol defined in the
   same object file.  It appears to simply discard such relocs, rather
   than adding their values into the object file.  We handle this here
   by converting all relocs against defined symbols into relocs
   against the section symbol, when generating a relocatable output
   file.

   Note that this function is only called if we are not using the COFF
   specific backend linker.  It only does something when doing a
   relocatable link, which will almost certainly fail when not
   generating COFF i960 output, so this function is actually no longer
   useful.  It was used before this target was converted to use the
   COFF specific backend linker.  */

static bfd_reloc_status_type
coff_i960_relocate (abfd, reloc_entry, symbol, data, input_section,
		    output_bfd, error_message)
     bfd *abfd;
     arelent *reloc_entry;
     asymbol *symbol;
     PTR data ATTRIBUTE_UNUSED;
     asection *input_section ATTRIBUTE_UNUSED;
     bfd *output_bfd;
     char **error_message ATTRIBUTE_UNUSED;
{
  asection *osec;

  if (output_bfd == NULL)
    {
      /* Not generating relocatable output file.  */
      return bfd_reloc_continue;
    }

  if (bfd_is_und_section (bfd_get_section (symbol)))
    {
      /* Symbol is not defined, so no need to worry about it.  */
      return bfd_reloc_continue;
    }

  if (bfd_is_com_section (bfd_get_section (symbol)))
    {
      /* I don't really know what the right action is for a common
         symbol.  */
      return bfd_reloc_continue;
    }

  /* Convert the reloc to use the section symbol.  FIXME: This method
     is ridiculous.  */
  osec = bfd_get_section (symbol)->output_section;
  if (coff_section_data (output_bfd, osec) != NULL
      && coff_section_data (output_bfd, osec)->tdata != NULL)
    reloc_entry->sym_ptr_ptr =
      (asymbol **) coff_section_data (output_bfd, osec)->tdata;
  else
    {
      const char *sec_name;
      asymbol **syms, **sym_end;

      sec_name = bfd_get_section_name (output_bfd, osec);
      syms = bfd_get_outsymbols (output_bfd);
      sym_end = syms + bfd_get_symcount (output_bfd);
      for (; syms < sym_end; syms++)
	{
	  if (bfd_asymbol_name (*syms) != NULL
	      && (*syms)->value == 0
	      && strcmp ((*syms)->section->output_section->name,
			 sec_name) == 0)
	    break;
	}

      if (syms >= sym_end)
	abort ();

      reloc_entry->sym_ptr_ptr = syms;

      if (coff_section_data (output_bfd, osec) == NULL)
	{
	  bfd_size_type amt = sizeof (struct coff_section_tdata);
	  osec->used_by_bfd = (PTR) bfd_zalloc (abfd, amt);
	  if (osec->used_by_bfd == NULL)
	    return bfd_reloc_overflow;
	}
      coff_section_data (output_bfd, osec)->tdata = (PTR) syms;
    }

  /* Let bfd_perform_relocation do its thing, which will include
     stuffing the symbol addend into the object file.  */
  return bfd_reloc_continue;
}

static reloc_howto_type howto_rellong =
  HOWTO ((unsigned int) R_RELLONG, 0, 2, 32,FALSE, 0,
	 complain_overflow_bitfield, coff_i960_relocate,"rellong", TRUE,
	 0xffffffff, 0xffffffff, 0);
static reloc_howto_type howto_iprmed =
  HOWTO (R_IPRMED, 0, 2, 24,TRUE,0, complain_overflow_signed,
	 coff_i960_relocate, "iprmed ", TRUE, 0x00ffffff, 0x00ffffff, 0);
static reloc_howto_type howto_optcall =
  HOWTO (R_OPTCALL, 0,2,24,TRUE,0, complain_overflow_signed,
	 optcall_callback, "optcall", TRUE, 0x00ffffff, 0x00ffffff, 0);

static reloc_howto_type *
coff_i960_reloc_type_lookup (abfd, code)
     bfd *abfd ATTRIBUTE_UNUSED;
     bfd_reloc_code_real_type code;
{
  switch (code)
    {
    default:
      return 0;
    case BFD_RELOC_I960_CALLJ:
      return &howto_optcall;
    case BFD_RELOC_32:
    case BFD_RELOC_CTOR:
      return &howto_rellong;
    case BFD_RELOC_24_PCREL:
      return &howto_iprmed;
    }
}

static reloc_howto_type *
coff_i960_reloc_name_lookup (bfd *abfd ATTRIBUTE_UNUSED,
			     const char *r_name)
{
  if (strcasecmp (howto_optcall.name, r_name) == 0)
    return &howto_optcall;
  if (strcasecmp (howto_rellong.name, r_name) == 0)
    return &howto_rellong;
  if (strcasecmp (howto_iprmed.name, r_name) == 0)
    return &howto_iprmed;

  return NULL;
}

/* The real code is in coffcode.h */

#define RTYPE2HOWTO(cache_ptr, dst) \
{							\
   reloc_howto_type *howto_ptr;				\
   switch ((dst)->r_type) {				\
     case 17: howto_ptr = &howto_rellong; break;	\
     case 25: howto_ptr = &howto_iprmed; break;		\
     case 27: howto_ptr = &howto_optcall; break;	\
     default: howto_ptr = 0; break;			\
     }							\
   (cache_ptr)->howto = howto_ptr;			\
 }

/* i960 COFF is used by VxWorks 5.1.  However, VxWorks 5.1 does not
   appear to correctly handle a reloc against a symbol defined in the
   same object file.  It appears to simply discard such relocs, rather
   than adding their values into the object file.  We handle this by
   converting all relocs against global symbols into relocs against
   internal symbols at the start of the section.  This routine is
   called at the start of the linking process, and it creates the
   necessary symbols.  */

static bfd_boolean
coff_i960_start_final_link (abfd, info)
     bfd *abfd;
     struct bfd_link_info *info;
{
  bfd_size_type symesz = bfd_coff_symesz (abfd);
  asection *o;
  bfd_byte *esym;

  if (! info->relocatable)
    return TRUE;

  esym = (bfd_byte *) bfd_malloc (symesz);
  if (esym == NULL)
    return FALSE;

  if (bfd_seek (abfd, obj_sym_filepos (abfd), SEEK_SET) != 0)
    return FALSE;

  for (o = abfd->sections; o != NULL; o = o->next)
    {
      struct internal_syment isym;

      strncpy (isym._n._n_name, o->name, SYMNMLEN);
      isym.n_value = 0;
      isym.n_scnum = o->target_index;
      isym.n_type = T_NULL;
      isym.n_sclass = C_STAT;
      isym.n_numaux = 0;

      bfd_coff_swap_sym_out (abfd, (PTR) &isym, (PTR) esym);

      if (bfd_bwrite (esym, symesz, abfd) != symesz)
	{
	  free (esym);
	  return FALSE;
	}

      obj_raw_syment_count (abfd) += 1;
    }

  free (esym);

  return TRUE;
}

/* The reloc processing routine for the optimized COFF linker.  */

static bfd_boolean
coff_i960_relocate_section (output_bfd, info, input_bfd, input_section,
			    contents, relocs, syms, sections)
     bfd *output_bfd ATTRIBUTE_UNUSED;
     struct bfd_link_info *info;
     bfd *input_bfd;
     asection *input_section;
     bfd_byte *contents;
     struct internal_reloc *relocs;
     struct internal_syment *syms;
     asection **sections;
{
  struct internal_reloc *rel;
  struct internal_reloc *relend;

  rel = relocs;
  relend = rel + input_section->reloc_count;
  for (; rel < relend; rel++)
    {
      long symndx;
      struct coff_link_hash_entry *h;
      struct internal_syment *sym;
      bfd_vma addend;
      bfd_vma val;
      reloc_howto_type *howto;
      bfd_reloc_status_type rstat = bfd_reloc_ok;
      bfd_boolean done;

      symndx = rel->r_symndx;

      if (symndx == -1)
	{
	  h = NULL;
	  sym = NULL;
	}
      else
	{
	  h = obj_coff_sym_hashes (input_bfd)[symndx];
	  sym = syms + symndx;
	}

      if (sym != NULL && sym->n_scnum != 0)
	addend = - sym->n_value;
      else
	addend = 0;

      switch (rel->r_type)
	{
	case 17: howto = &howto_rellong; break;
	case 25: howto = &howto_iprmed; break;
	case 27: howto = &howto_optcall; break;
	default:
	  bfd_set_error (bfd_error_bad_value);
	  return FALSE;
	}

      val = 0;

      if (h == NULL)
	{
	  asection *sec;

	  if (symndx == -1)
	    {
	      sec = bfd_abs_section_ptr;
	      val = 0;
	    }
	  else
	    {
	      sec = sections[symndx];
              val = (sec->output_section->vma
		     + sec->output_offset
		     + sym->n_value
		     - sec->vma);
	    }
	}
      else
	{
	  if (h->root.type == bfd_link_hash_defined
	      || h->root.type == bfd_link_hash_defweak)
	    {
	      asection *sec;

	      sec = h->root.u.def.section;
	      val = (h->root.u.def.value
		     + sec->output_section->vma
		     + sec->output_offset);
	    }
	  else if (! info->relocatable)
	    {
	      if (! ((*info->callbacks->undefined_symbol)
		     (info, h->root.root.string, input_bfd, input_section,
		      rel->r_vaddr - input_section->vma, TRUE)))
		return FALSE;
	    }
	}

      done = FALSE;

      if (howto->type == R_OPTCALL && ! info->relocatable && symndx != -1)
	{
	  int class;

	  if (h != NULL)
	    class = h->class;
	  else
	    class = sym->n_sclass;

	  switch (class)
	    {
	    case C_NULL:
	      /* This symbol is apparently not from a COFF input file.
                 We warn, and then assume that it is not a leaf
                 function.  */
	      if (! ((*info->callbacks->reloc_dangerous)
		     (info,
		      _("uncertain calling convention for non-COFF symbol"),
		      input_bfd, input_section,
		      rel->r_vaddr - input_section->vma)))
		return FALSE;
	      break;
	    case C_LEAFSTAT:
	    case C_LEAFEXT:
	      /* This is a call to a leaf procedure; use the bal
                 instruction.  */
	      {
		long olf;
		unsigned long word;

		if (h != NULL)
		  {
		    BFD_ASSERT (h->numaux == 2);
		    olf = h->aux[1].x_bal.x_balntry;
		  }
		else
		  {
		    bfd_byte *esyms;
		    union internal_auxent aux;

		    BFD_ASSERT (sym->n_numaux == 2);
		    esyms = (bfd_byte *) obj_coff_external_syms (input_bfd);
		    esyms += (symndx + 2) * bfd_coff_symesz (input_bfd);
		    bfd_coff_swap_aux_in (input_bfd, (PTR) esyms, sym->n_type,
					  sym->n_sclass, 1, sym->n_numaux,
					  (PTR) &aux);
		    olf = aux.x_bal.x_balntry;
		  }

		word = bfd_get_32 (input_bfd,
				   (contents
				    + (rel->r_vaddr - input_section->vma)));
		word = ((word + olf - val) & BAL_MASK) | BAL;
		bfd_put_32 (input_bfd,
			    (bfd_vma) word,
			    contents + (rel->r_vaddr - input_section->vma));
		done = TRUE;
	      }
	      break;
	    case C_SCALL:
	      BFD_ASSERT (0);
	      break;
	    }
	}

      if (! done)
	{
	  if (howto->pc_relative)
	    addend += input_section->vma;
	  rstat = _bfd_final_link_relocate (howto, input_bfd, input_section,
					    contents,
					    rel->r_vaddr - input_section->vma,
					    val, addend);
	}

      switch (rstat)
	{
	default:
	  abort ();
	case bfd_reloc_ok:
	  break;
	case bfd_reloc_overflow:
	  {
	    const char *name;
	    char buf[SYMNMLEN + 1];

	    if (symndx == -1)
	      name = "*ABS*";
	    else if (h != NULL)
	      name = NULL;
	    else
	      {
		name = _bfd_coff_internal_syment_name (input_bfd, sym, buf);
		if (name == NULL)
		  return FALSE;
	      }

	    if (! ((*info->callbacks->reloc_overflow)
		   (info, (h ? &h->root : NULL), name, howto->name,
		    (bfd_vma) 0, input_bfd, input_section,
		    rel->r_vaddr - input_section->vma)))
	      return FALSE;
	  }
	}
    }

  return TRUE;
}

/* Adjust the symbol index of any reloc against a global symbol to
   instead be a reloc against the internal symbol we created specially
   for the section.  */

static bfd_boolean
coff_i960_adjust_symndx (obfd, info, ibfd, sec, irel, adjustedp)
     bfd *obfd ATTRIBUTE_UNUSED;
     struct bfd_link_info *info ATTRIBUTE_UNUSED;
     bfd *ibfd;
     asection *sec ATTRIBUTE_UNUSED;
     struct internal_reloc *irel;
     bfd_boolean *adjustedp;
{
  struct coff_link_hash_entry *h;

  *adjustedp = FALSE;

  h = obj_coff_sym_hashes (ibfd)[irel->r_symndx];
  if (h == NULL
      || (h->root.type != bfd_link_hash_defined
	  && h->root.type != bfd_link_hash_defweak))
    return TRUE;

  irel->r_symndx = h->root.u.def.section->output_section->target_index - 1;
  *adjustedp = TRUE;

  return TRUE;
}

#define coff_bfd_is_local_label_name coff_i960_is_local_label_name

#define coff_start_final_link coff_i960_start_final_link

#define coff_relocate_section coff_i960_relocate_section

#define coff_adjust_symndx coff_i960_adjust_symndx

#define coff_bfd_reloc_type_lookup coff_i960_reloc_type_lookup
#define coff_bfd_reloc_name_lookup coff_i960_reloc_name_lookup

#include "coffcode.h"

extern const bfd_target icoff_big_vec;

CREATE_LITTLE_COFF_TARGET_VEC (icoff_little_vec, "coff-Intel-little", 0, 0, '_', & icoff_big_vec, COFF_SWAP_TABLE)

const bfd_target icoff_big_vec =
{
  "coff-Intel-big",		/* name */
  bfd_target_coff_flavour,
  BFD_ENDIAN_LITTLE,		/* data byte order is little */
  BFD_ENDIAN_BIG,		/* header byte order is big */

  (HAS_RELOC | EXEC_P |		/* object flags */
   HAS_LINENO | HAS_DEBUG |
   HAS_SYMS | HAS_LOCALS | WP_TEXT),

  (SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD | SEC_RELOC), /* section flags */
  '_',				/* leading underscore */
  '/',				/* ar_pad_char */
  15,				/* ar_max_namelen */

bfd_getl64, bfd_getl_signed_64, bfd_putl64,
     bfd_getl32, bfd_getl_signed_32, bfd_putl32,
     bfd_getl16, bfd_getl_signed_16, bfd_putl16, /* data */
bfd_getb64, bfd_getb_signed_64, bfd_putb64,
     bfd_getb32, bfd_getb_signed_32, bfd_putb32,
     bfd_getb16, bfd_getb_signed_16, bfd_putb16, /* hdrs */

  {_bfd_dummy_target, coff_object_p, /* bfd_check_format */
     bfd_generic_archive_p, _bfd_dummy_target},
  {bfd_false, coff_mkobject,	/* bfd_set_format */
     _bfd_generic_mkarchive, bfd_false},
  {bfd_false, coff_write_object_contents,	/* bfd_write_contents */
     _bfd_write_archive_contents, bfd_false},

     BFD_JUMP_TABLE_GENERIC (coff),
     BFD_JUMP_TABLE_COPY (coff),
     BFD_JUMP_TABLE_CORE (_bfd_nocore),
     BFD_JUMP_TABLE_ARCHIVE (_bfd_archive_coff),
     BFD_JUMP_TABLE_SYMBOLS (coff),
     BFD_JUMP_TABLE_RELOCS (coff),
     BFD_JUMP_TABLE_WRITE (coff),
     BFD_JUMP_TABLE_LINK (coff),
     BFD_JUMP_TABLE_DYNAMIC (_bfd_nodynamic),

  & icoff_little_vec,

  COFF_SWAP_TABLE
};
