/* 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;
     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;
{
  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);
}
