/* BFD back-end for ns32k a.out-ish binaries.
   Copyright (C) 1990, 91, 92, 94, 95, 96, 1998 Free Software Foundation, Inc.
   Contributed by Ian Dall (idall@eleceng.adelaide.edu.au).

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 2 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */

#define BYTES_IN_WORD 4

#include "bfd.h"
#include "aout/aout64.h"
#include "ns32k.h"

#define MYNS(OP) CAT(ns32kaout_,OP)
reloc_howto_type *
MYNS(bfd_reloc_type_lookup)
  PARAMS((bfd *abfd AND
	  bfd_reloc_code_real_type code));

boolean
MYNS(write_object_contents)
  PARAMS((bfd *abfd));

/* Avoid multiple definitions from aoutx if supporting standard a.out format(s)
 * as well as this one
 */
#define NAME(x,y) CAT3(ns32kaout,_32_,y)

void bfd_ns32k_arch PARAMS ((void));

#include "libaout.h"

#define MY(OP) MYNS(OP)

#define MY_swap_std_reloc_in MY(swap_std_reloc_in)
#define MY_swap_std_reloc_out MY(swap_std_reloc_out)

static void
MY_swap_std_reloc_in PARAMS ((bfd *abfd, struct reloc_std_external *bytes,
			      arelent *cache_ptr, asymbol **symbols,
			      bfd_size_type symcount));

static void
MY_swap_std_reloc_out PARAMS ((bfd *abfd, arelent *g,
			       struct reloc_std_external *natptr));

/* The ns32k series is ah, unusual, when it comes to relocation.
 * There are three storage methods for relocateable objects.  There
 * are displacements, immediate operands and ordinary twos complement
 * data. Of these, only the last fits into the standard relocation
 * scheme.  Immediate operands are stored huffman encoded and
 * immediate operands are stored big endian (where as the natural byte
 * order is little endian for this achitecture).

 * Note that the ns32k displacement storage method is orthogonal to
 * whether the relocation is pc relative or not. The "displacement"
 * storage scheme is used for essentially all address constants. The
 * displacement can be relative to zero (absolute displacement),
 * relative to the pc (pc relative), the stack pointer, the frame
 * pointer, the static base register and general purpose register etc.

 * For example:
 *
 *  sym1: .long .	# pc relative 2's complement
 *  sym1: .long foo	# 2's complement not pc relative
 *
 *  self:  movd @self, r0 # pc relative displacement
 *	   movd foo, r0 # non pc relative displacement
 *
 *  self:  movd self, r0 # pc relative immediate
 *         movd foo, r0 # non pc relative immediate
 *
 * In addition, for historical reasons the encoding of the relocation types
 * in the a.out format relocation entries is such that even the relocation
 * methods which are standard are not encoded the standard way.
 *
 */

reloc_howto_type MY(howto_table)[] = 
{
  /* ns32k immediate operands */
  HOWTO (BFD_RELOC_NS32K_IMM_8, 0, 0, 8, false, 0, true,
	 _bfd_ns32k_reloc_imm, "NS32K_IMM_8",
	 true, 0x000000ff,0x000000ff, false),
  HOWTO (BFD_RELOC_NS32K_IMM_16, 0, 1, 16, false, 0, true,
	 _bfd_ns32k_reloc_imm,  "NS32K_IMM_16",
	 true, 0x0000ffff,0x0000ffff, false),
  HOWTO (BFD_RELOC_NS32K_IMM_32, 0, 2, 32, false, 0, true,
	 _bfd_ns32k_reloc_imm, "NS32K_IMM_32",
	 true, 0xffffffff,0xffffffff, false),
  HOWTO (BFD_RELOC_NS32K_IMM_8_PCREL, 0, 0, 8, true, 0, false,
	 _bfd_ns32k_reloc_imm, "PCREL_NS32K_IMM_8",
	 true, 0x000000ff, 0x000000ff, false),
  HOWTO (BFD_RELOC_NS32K_IMM_16_PCREL, 0, 1, 16, true, 0, false,
	 _bfd_ns32k_reloc_imm, "PCREL_NS32K_IMM_16",
	 true, 0x0000ffff,0x0000ffff, false),
  HOWTO (BFD_RELOC_NS32K_IMM_32_PCREL, 0, 2, 32, true, 0, false,
	 _bfd_ns32k_reloc_imm, "PCREL_NS32K_IMM_32",
	 true, 0xffffffff,0xffffffff, false),

  /* ns32k displacements */
  HOWTO (BFD_RELOC_NS32K_DISP_8, 0, 0, 8, false, 0, true,
	 _bfd_ns32k_reloc_disp, "NS32K_DISP_8",
	 true, 0x000000ff,0x000000ff, false),
  HOWTO (BFD_RELOC_NS32K_DISP_16, 0, 1, 16, false, 0, true,
	 _bfd_ns32k_reloc_disp, "NS32K_DISP_16",
	 true, 0x0000ffff, 0x0000ffff, false),
  HOWTO (BFD_RELOC_NS32K_DISP_32, 0, 2, 32, false, 0, true,
	 _bfd_ns32k_reloc_disp, "NS32K_DISP_32",
	 true, 0xffffffff, 0xffffffff, false),
  HOWTO (BFD_RELOC_NS32K_DISP_8_PCREL, 0, 0, 8, true, 0, false,
	 _bfd_ns32k_reloc_disp, "PCREL_NS32K_DISP_8",
	 true, 0x000000ff,0x000000ff, false),
  HOWTO (BFD_RELOC_NS32K_DISP_16_PCREL, 0, 1, 16, true, 0, false,
	 _bfd_ns32k_reloc_disp, "PCREL_NS32K_DISP_16",
	 true, 0x0000ffff,0x0000ffff, false),
  HOWTO (BFD_RELOC_NS32K_DISP_32_PCREL, 0, 2, 32, true, 0, false,
	 _bfd_ns32k_reloc_disp, "PCREL_NS32K_DISP_32",
	 true, 0xffffffff,0xffffffff, false),

  /* Normal 2's complement */
  HOWTO (BFD_RELOC_8, 0, 0, 8, false, 0, complain_overflow_bitfield,0,
	 "8", true, 0x000000ff,0x000000ff, false),
  HOWTO (BFD_RELOC_16, 0, 1, 16, false, 0, complain_overflow_bitfield,0,
	 "16", true, 0x0000ffff,0x0000ffff, false),
  HOWTO (BFD_RELOC_32, 0, 2, 32, false, 0, complain_overflow_bitfield,0,
	 "32", true, 0xffffffff,0xffffffff, false),
  HOWTO (BFD_RELOC_8_PCREL, 0, 0, 8, true, 0, complain_overflow_signed, 0,
	 "PCREL_8", true, 0x000000ff,0x000000ff, false),
  HOWTO (BFD_RELOC_16_PCREL, 0, 1, 16, true, 0, complain_overflow_signed, 0,
	 "PCREL_16", true, 0x0000ffff,0x0000ffff, false),
  HOWTO (BFD_RELOC_32_PCREL, 0, 2, 32, true, 0, complain_overflow_signed, 0,
	 "PCREL_32", true, 0xffffffff,0xffffffff, false),
};


#define CTOR_TABLE_RELOC_HOWTO(BFD) (MY(howto_table) + 14)

#define RELOC_STD_BITS_NS32K_TYPE_BIG 0x06
#define RELOC_STD_BITS_NS32K_TYPE_LITTLE 0x60
#define RELOC_STD_BITS_NS32K_TYPE_SH_BIG 1
#define RELOC_STD_BITS_NS32K_TYPE_SH_LITTLE 5

reloc_howto_type *
MY(reloc_howto)(abfd, rel, r_index, r_extern, r_pcrel)
     bfd *abfd ATTRIBUTE_UNUSED;
     struct reloc_std_external *rel;
     int *r_index;
     int *r_extern;
     int *r_pcrel;
{
  unsigned int r_length;
  int r_ns32k_type;
/*  BFD_ASSERT(bfd_header_little_endian (abfd)); */
  *r_index =  ((rel->r_index[2] << 16)
	       | (rel->r_index[1] << 8)
	       |  rel->r_index[0] );
  *r_extern  = (0 != (rel->r_type[0] & RELOC_STD_BITS_EXTERN_LITTLE));
  *r_pcrel   = (0 != (rel->r_type[0] & RELOC_STD_BITS_PCREL_LITTLE));
  r_length  =  ((rel->r_type[0] & RELOC_STD_BITS_LENGTH_LITTLE)
		>> RELOC_STD_BITS_LENGTH_SH_LITTLE);
  r_ns32k_type  =  ((rel->r_type[0] & RELOC_STD_BITS_NS32K_TYPE_LITTLE)
		    >> RELOC_STD_BITS_NS32K_TYPE_SH_LITTLE);
  return (MY(howto_table) + r_length + 3 * (*r_pcrel) + 6 * r_ns32k_type);
}

#define MY_reloc_howto(BFD,REL,IN,EX,PC) MY(reloc_howto)(BFD, REL, &IN, &EX, &PC)

void
MY(put_reloc)(abfd, r_extern, r_index, value, howto, reloc)
     bfd *abfd;
     int r_extern;
     int r_index;
     long value;
     reloc_howto_type *howto;
     struct reloc_std_external *reloc;
{
  unsigned int r_length;
  int r_pcrel;
  int r_ns32k_type;
  PUT_WORD (abfd, value, reloc->r_address);
  r_length = howto->size ;	/* Size as a power of two */
  r_pcrel  = (int) howto->pc_relative; /* Relative to PC? */
  r_ns32k_type = (howto - MY(howto_table) )/6;
/*  BFD_ASSERT (bfd_header_little_endian (abfd)); */
  reloc->r_index[2] = r_index >> 16;
  reloc->r_index[1] = r_index >> 8;
  reloc->r_index[0] = r_index;
  reloc->r_type[0] =
    (r_extern?    RELOC_STD_BITS_EXTERN_LITTLE: 0)
      | (r_pcrel?     RELOC_STD_BITS_PCREL_LITTLE: 0)
	| (r_length <<  RELOC_STD_BITS_LENGTH_SH_LITTLE)
	  | (r_ns32k_type <<  RELOC_STD_BITS_NS32K_TYPE_SH_LITTLE);
}

#define MY_put_reloc(BFD, EXT, IDX, VAL, HOWTO, RELOC) \
  MY(put_reloc)(BFD, EXT, IDX, VAL, HOWTO, RELOC)

#define STAT_FOR_EXEC

#define MY_final_link_relocate _bfd_ns32k_final_link_relocate
#define MY_relocate_contents _bfd_ns32k_relocate_contents

#include <aoutx.h>

reloc_howto_type *
MY(bfd_reloc_type_lookup)(abfd,code)
     bfd *abfd;
     bfd_reloc_code_real_type code;
{

#define ENTRY(i,j)	case i: return &MY(howto_table)[j]

  int ext = obj_reloc_entry_size (abfd) == RELOC_EXT_SIZE;

  BFD_ASSERT(ext == 0);
  if (code == BFD_RELOC_CTOR)
    switch (bfd_get_arch_info (abfd)->bits_per_address)
      {
      case 32:
	code = BFD_RELOC_32;
	break;
      }
  switch (code)
    {
      ENTRY(BFD_RELOC_NS32K_IMM_8, 0);
      ENTRY(BFD_RELOC_NS32K_IMM_16, 1);
      ENTRY(BFD_RELOC_NS32K_IMM_32, 2);
      ENTRY(BFD_RELOC_NS32K_IMM_8_PCREL, 3);
      ENTRY(BFD_RELOC_NS32K_IMM_16_PCREL, 4);
      ENTRY(BFD_RELOC_NS32K_IMM_32_PCREL, 5);
      ENTRY(BFD_RELOC_NS32K_DISP_8, 6);
      ENTRY(BFD_RELOC_NS32K_DISP_16, 7);
      ENTRY(BFD_RELOC_NS32K_DISP_32, 8);
      ENTRY(BFD_RELOC_NS32K_DISP_8_PCREL, 9);
      ENTRY(BFD_RELOC_NS32K_DISP_16_PCREL, 10);
      ENTRY(BFD_RELOC_NS32K_DISP_32_PCREL, 11);
      ENTRY(BFD_RELOC_8, 12);
      ENTRY(BFD_RELOC_16, 13);
      ENTRY(BFD_RELOC_32, 14);
      ENTRY(BFD_RELOC_8_PCREL, 15);
      ENTRY(BFD_RELOC_16_PCREL, 16);
      ENTRY(BFD_RELOC_32_PCREL, 17);
    default: return (reloc_howto_type *) NULL;
    }
#undef ENTRY
}


static void
MY_swap_std_reloc_in (abfd, bytes, cache_ptr, symbols, symcount)
     bfd *abfd;
     struct reloc_std_external *bytes;
     arelent *cache_ptr;
     asymbol **symbols;
     bfd_size_type symcount ATTRIBUTE_UNUSED;
{
  int r_index;
  int r_extern;
  int r_pcrel;
  struct aoutdata  *su = &(abfd->tdata.aout_data->a);

  cache_ptr->address = bfd_h_get_32 (abfd, bytes->r_address);

  /* now the fun stuff */

  cache_ptr->howto = MY_reloc_howto(abfd, bytes, r_index, r_extern, r_pcrel);

  MOVE_ADDRESS(0);
}

static void
MY_swap_std_reloc_out (abfd, g, natptr)
     bfd *abfd;
     arelent *g;
     struct reloc_std_external *natptr;
{
  int r_index;
  asymbol *sym = *(g->sym_ptr_ptr);
  int r_extern;
  unsigned int r_addend;
  asection *output_section = sym->section->output_section;

  r_addend = g->addend + (*(g->sym_ptr_ptr))->section->output_section->vma;
    
  /* name was clobbered by aout_write_syms to be symbol index */

  /* If this relocation is relative to a symbol then set the 
     r_index to the symbols index, and the r_extern bit.

     Absolute symbols can come in in two ways, either as an offset
     from the abs section, or as a symbol which has an abs value.
     Check for that here.  */

  if (bfd_is_com_section (output_section)
      || output_section == &bfd_abs_section
      || output_section == &bfd_und_section) 
    {
      if (bfd_abs_section.symbol == sym)
	{
	  /* Whoops, looked like an abs symbol, but is really an offset
	     from the abs section */
	  r_index = 0;
	  r_extern = 0;
	}
      else 
	{
	  /* Fill in symbol */
	  r_extern = 1;
#undef KEEPIT
#define KEEPIT udata.i
	  r_index =  (*(g->sym_ptr_ptr))->KEEPIT;
#undef KEEPIT     
	}
    }
  else 
    {
      /* Just an ordinary section */
      r_extern = 0;
      r_index  = output_section->target_index;      
    }

  MY_put_reloc (abfd, r_extern, r_index, g->address, g->howto, natptr);
}

bfd_reloc_status_type
_bfd_ns32k_relocate_contents (howto, input_bfd, relocation, location)
     reloc_howto_type *howto;
     bfd *input_bfd;
     bfd_vma relocation;
     bfd_byte *location;
{
  int r_ns32k_type = (howto - MY(howto_table)) / 6;
  long (*get_data) PARAMS ((bfd_byte *, long, long));
  int (*put_data) PARAMS ((long, bfd_byte *, long, long));

  switch (r_ns32k_type)
    {
    case 0:
      get_data = _bfd_ns32k_get_immediate;
      put_data = _bfd_ns32k_put_immediate;
      break;
    case 1:
      get_data = _bfd_ns32k_get_displacement;
      put_data = _bfd_ns32k_put_displacement;
      break;
    case 2:
      return _bfd_relocate_contents (howto, input_bfd, relocation,
				    location);
      /* NOT REACHED */
      break;
    default:
      return bfd_reloc_notsupported;
    }
  return _bfd_do_ns32k_reloc_contents (howto, input_bfd, relocation,
				       location, get_data, put_data);
}
