/* BFD back-end for ns32k a.out-ish binaries.
   Copyright (C) 1990-2021 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 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.  */

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

/* Do not "beautify" the CONCAT* macro args.  Traditional C will not
   remove whitespace added here, and thus will fail to concatenate
   the tokens.  */
#define MYNS(OP) CONCAT2 (ns32k_aout_,OP)

reloc_howto_type * MYNS (bfd_reloc_type_lookup) (bfd *, bfd_reloc_code_real_type);
reloc_howto_type * MYNS (bfd_reloc_name_lookup) (bfd *, const char *);
bool MYNS (write_object_contents) (bfd *);

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

void bfd_ns32k_arch (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)

/* The ns32k series is ah, unusual, when it comes to relocation.
   There are three storage methods for relocatable 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 architecture).

   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, complain_overflow_signed,
	 _bfd_ns32k_reloc_imm, "NS32K_IMM_8",
	 true, 0x000000ff,0x000000ff, false),
  HOWTO (BFD_RELOC_NS32K_IMM_16, 0, 1, 16, false, 0, complain_overflow_signed,
	 _bfd_ns32k_reloc_imm,  "NS32K_IMM_16",
	 true, 0x0000ffff,0x0000ffff, false),
  HOWTO (BFD_RELOC_NS32K_IMM_32, 0, 2, 32, false, 0, complain_overflow_signed,
	 _bfd_ns32k_reloc_imm, "NS32K_IMM_32",
	 true, 0xffffffff,0xffffffff, false),
  HOWTO (BFD_RELOC_NS32K_IMM_8_PCREL, 0, 0, 8, true, 0, complain_overflow_signed,
	 _bfd_ns32k_reloc_imm, "PCREL_NS32K_IMM_8",
	 true, 0x000000ff, 0x000000ff, false),
  HOWTO (BFD_RELOC_NS32K_IMM_16_PCREL, 0, 1, 16, true, 0, complain_overflow_signed,
	 _bfd_ns32k_reloc_imm, "PCREL_NS32K_IMM_16",
	 true, 0x0000ffff,0x0000ffff, false),
  HOWTO (BFD_RELOC_NS32K_IMM_32_PCREL, 0, 2, 32, true, 0, complain_overflow_signed,
	 _bfd_ns32k_reloc_imm, "PCREL_NS32K_IMM_32",
	 true, 0xffffffff,0xffffffff, false),

  /* ns32k displacements.  */
  HOWTO (BFD_RELOC_NS32K_DISP_8, 0, 0, 7, false, 0, complain_overflow_signed,
	 _bfd_ns32k_reloc_disp, "NS32K_DISP_8",
	 true, 0x000000ff,0x000000ff, false),
  HOWTO (BFD_RELOC_NS32K_DISP_16, 0, 1, 14, false, 0, complain_overflow_signed,
	 _bfd_ns32k_reloc_disp, "NS32K_DISP_16",
	 true, 0x0000ffff, 0x0000ffff, false),
  HOWTO (BFD_RELOC_NS32K_DISP_32, 0, 2, 30, false, 0, complain_overflow_signed,
	 _bfd_ns32k_reloc_disp, "NS32K_DISP_32",
	 true, 0xffffffff, 0xffffffff, false),
  HOWTO (BFD_RELOC_NS32K_DISP_8_PCREL, 0, 0, 7, true, 0, complain_overflow_signed,
	   _bfd_ns32k_reloc_disp, "PCREL_NS32K_DISP_8",
	 true, 0x000000ff,0x000000ff, false),
  HOWTO (BFD_RELOC_NS32K_DISP_16_PCREL, 0, 1, 14, true, 0, complain_overflow_signed,
	 _bfd_ns32k_reloc_disp, "PCREL_NS32K_DISP_16",
	 true, 0x0000ffff,0x0000ffff, false),
  HOWTO (BFD_RELOC_NS32K_DISP_32_PCREL, 0, 2, 30, true, 0, complain_overflow_signed,
	 _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

static reloc_howto_type *
MY (reloc_howto) (bfd *abfd ATTRIBUTE_UNUSED,
		  struct reloc_std_external *rel,
		  unsigned int *r_index,
		  int *r_extern,
		  int *r_pcrel)
{
  unsigned int r_length;
  unsigned int r_ns32k_type;

  *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);
  if (r_length > 2 || r_ns32k_type > 2)
    return NULL;
  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)

static void
MY (put_reloc) (bfd *abfd,
		int r_extern,
		int r_index,
		bfd_vma 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;

  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

static void MY_swap_std_reloc_in (bfd *, struct reloc_std_external *, arelent *, asymbol **, bfd_size_type);
static void MY_swap_std_reloc_out (bfd *, arelent *, struct reloc_std_external *);

#include "aoutx.h"

reloc_howto_type *
MY (bfd_reloc_type_lookup) (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_arch_bits_per_address (abfd))
      {
      case 32:
	code = BFD_RELOC_32;
	break;
      default:
	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 NULL;
    }
#undef ENTRY
}

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

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

  return NULL;
}

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

  cache_ptr->address = 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 (bfd *abfd,
		       arelent *g,
		       struct reloc_std_external *natptr)
{
  int r_index;
  asymbol *sym = *(g->sym_ptr_ptr);
  int r_extern;
  asection *output_section = sym->section->output_section;

  /* 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)
      || bfd_is_abs_section (output_section)
      || bfd_is_und_section (output_section))
    {
      if (bfd_abs_section_ptr->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 (reloc_howto_type *howto,
			      bfd *input_bfd,
			      bfd_vma relocation,
			      bfd_byte *location)
{
  int r_ns32k_type = (howto - MY (howto_table)) / 6;
  bfd_vma (*get_data) (bfd_byte *, int);
  void (*put_data) (bfd_vma, bfd_byte *, int);

  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);
    default:
      return bfd_reloc_notsupported;
    }
  return _bfd_do_ns32k_reloc_contents (howto, input_bfd, relocation,
				       location, get_data, put_data);
}
