/* BFD backend for MIPS BSD (a.out) binaries.
   Copyright 1993, 1994, 1995, 1997, 1998, 1999, 2000, 2001, 2002
   Free Software Foundation, Inc.
   Written by Ralph Campbell.

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
/* #define ENTRY_CAN_BE_ZERO */
#define N_HEADER_IN_TEXT(x) 1
#define N_SHARED_LIB(x) 0
#define N_TXTADDR(x) \
    (N_MAGIC(x) != ZMAGIC ? (x).a_entry :	/* object file or NMAGIC */\
	    TEXT_START_ADDR + EXEC_BYTES_SIZE	/* no padding */\
    )
#define N_DATADDR(x) (N_TXTADDR(x)+N_TXTSIZE(x))
#define TEXT_START_ADDR 4096
#define TARGET_PAGE_SIZE 4096
#define SEGMENT_SIZE TARGET_PAGE_SIZE
#define DEFAULT_ARCH bfd_arch_mips
#define MACHTYPE_OK(mtype) ((mtype) == M_UNKNOWN \
			    || (mtype) == M_MIPS1 || (mtype) == M_MIPS2)
#define MY_symbol_leading_char '\0'

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

#include "bfd.h"
#include "sysdep.h"
#include "libbfd.h"
#include "libaout.h"

#define SET_ARCH_MACH(ABFD, EXEC) \
  MY(set_arch_mach) (ABFD, N_MACHTYPE (EXEC)); \
  MY(choose_reloc_size) (ABFD);
static void MY(set_arch_mach) PARAMS ((bfd *abfd, unsigned long machtype));
static void MY(choose_reloc_size) PARAMS ((bfd *abfd));

#define MY_write_object_contents MY(write_object_contents)
static boolean MY(write_object_contents) PARAMS ((bfd *abfd));

/* We can't use MY(x) here because it leads to a recursive call to CONCAT2
   when expanded inside JUMP_TABLE.  */
#define MY_bfd_reloc_type_lookup mipsbsd_reloc_howto_type_lookup
#define MY_canonicalize_reloc mipsbsd_canonicalize_reloc

#define MY_bfd_link_hash_table_create _bfd_generic_link_hash_table_create
#define MY_bfd_link_add_symbols _bfd_generic_link_add_symbols
#define MY_final_link_callback unused
#define MY_bfd_final_link _bfd_generic_final_link

#define MY_backend_data &MY(backend_data)
#define MY_BFD_TARGET

#include "aout-target.h"

static bfd_reloc_status_type mips_fix_jmp_addr
  PARAMS ((bfd *, arelent *, struct symbol_cache_entry *, PTR, asection *,
	   bfd *, char **));
static reloc_howto_type *MY(reloc_howto_type_lookup)
  PARAMS ((bfd *, bfd_reloc_code_real_type));

long MY(canonicalize_reloc) PARAMS ((bfd *, sec_ptr, arelent **, asymbol **));

static void
MY(set_arch_mach) (abfd, machtype)
     bfd *abfd;
     unsigned long machtype;
{
  enum bfd_architecture arch;
  unsigned int machine;

  /* Determine the architecture and machine type of the object file.  */
  switch (machtype)
    {
    case M_MIPS1:
      arch = bfd_arch_mips;
      machine = bfd_mach_mips3000;
      break;

    case M_MIPS2:
      arch = bfd_arch_mips;
      machine = bfd_mach_mips4000;
      break;

    default:
      arch = bfd_arch_obscure;
      machine = 0;
      break;
    }

  bfd_set_arch_mach (abfd, arch, machine);
}

/* Determine the size of a relocation entry, based on the architecture */
static void
MY (choose_reloc_size) (abfd)
     bfd *abfd;
{
  switch (bfd_get_arch (abfd))
    {
    case bfd_arch_sparc:
    case bfd_arch_a29k:
    case bfd_arch_mips:
      obj_reloc_entry_size (abfd) = RELOC_EXT_SIZE;
      break;
    default:
      obj_reloc_entry_size (abfd) = RELOC_STD_SIZE;
      break;
    }
}

/* Write an object file in BSD a.out format.
  Section contents have already been written.  We write the
  file header, symbols, and relocation.  */

static boolean
MY (write_object_contents) (abfd)
     bfd *abfd;
{
  struct external_exec exec_bytes;
  struct internal_exec *execp = exec_hdr (abfd);

  /* Magic number, maestro, please!  */
  switch (bfd_get_arch (abfd))
    {
    case bfd_arch_m68k:
      switch (bfd_get_mach (abfd))
	{
	case bfd_mach_m68010:
	  N_SET_MACHTYPE (*execp, M_68010);
	  break;
	default:
	case bfd_mach_m68020:
	  N_SET_MACHTYPE (*execp, M_68020);
	  break;
	}
      break;
    case bfd_arch_sparc:
      N_SET_MACHTYPE (*execp, M_SPARC);
      break;
    case bfd_arch_i386:
      N_SET_MACHTYPE (*execp, M_386);
      break;
    case bfd_arch_a29k:
      N_SET_MACHTYPE (*execp, M_29K);
      break;
    case bfd_arch_mips:
      switch (bfd_get_mach (abfd))
	{
	case bfd_mach_mips4000:
	case bfd_mach_mips6000:
	  N_SET_MACHTYPE (*execp, M_MIPS2);
	  break;
	default:
	  N_SET_MACHTYPE (*execp, M_MIPS1);
	  break;
	}
      break;
    default:
      N_SET_MACHTYPE (*execp, M_UNKNOWN);
    }

  MY (choose_reloc_size) (abfd);

  WRITE_HEADERS (abfd, execp);

  return true;
}

/* MIPS relocation types.  */
#define MIPS_RELOC_32		0
#define MIPS_RELOC_JMP		1
#define MIPS_RELOC_WDISP16	2
#define MIPS_RELOC_HI16		3
#define MIPS_RELOC_HI16_S	4
#define MIPS_RELOC_LO16		5

/* This is only called when performing a BFD_RELOC_MIPS_JMP relocation.
   The jump destination address is formed from the upper 4 bits of the
   "current" program counter concatenated with the jump instruction's
   26 bit field and two trailing zeros.
   If the destination address is not in the same segment as the "current"
   program counter, then we need to signal an error.  */

static bfd_reloc_status_type
mips_fix_jmp_addr (abfd, reloc_entry, symbol, data, input_section, output_bfd,
		   error_message)
     bfd *abfd ATTRIBUTE_UNUSED;
     arelent *reloc_entry;
     struct symbol_cache_entry *symbol;
     PTR data ATTRIBUTE_UNUSED;
     asection *input_section;
     bfd *output_bfd;
     char **error_message ATTRIBUTE_UNUSED;
{
  bfd_vma relocation, pc;

  /* If this is a partial relocation, just continue.  */
  if (output_bfd != (bfd *)NULL)
    return bfd_reloc_continue;

  /* If this is an undefined symbol, return error */
  if (bfd_is_und_section (symbol->section)
      && (symbol->flags & BSF_WEAK) == 0)
    return bfd_reloc_undefined;

  /* Work out which section the relocation is targetted at and the
     initial relocation command value.  */
  if (bfd_is_com_section (symbol->section))
    relocation = 0;
  else
    relocation = symbol->value;

  relocation += symbol->section->output_section->vma;
  relocation += symbol->section->output_offset;
  relocation += reloc_entry->addend;

  pc = input_section->output_section->vma + input_section->output_offset +
    reloc_entry->address + 4;

  if ((relocation & 0xF0000000) != (pc & 0xF0000000))
    return bfd_reloc_overflow;

  return bfd_reloc_continue;
}

/* This is only called when performing a BFD_RELOC_HI16_S relocation.
   We need to see if bit 15 is set in the result. If it is, we add
   0x10000 and continue normally. This will compensate for the sign extension
   when the low bits are added at run time.  */

static bfd_reloc_status_type
mips_fix_hi16_s PARAMS ((bfd *, arelent *, asymbol *, PTR,
			 asection *, bfd *, char **));

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

  /* If this is a partial relocation, just continue.  */
  if (output_bfd != (bfd *)NULL)
    return bfd_reloc_continue;

  /* If this is an undefined symbol, return error.  */
  if (bfd_is_und_section (symbol->section)
      && (symbol->flags & BSF_WEAK) == 0)
    return bfd_reloc_undefined;

  /* Work out which section the relocation is targetted at and the
     initial relocation command value.  */
  if (bfd_is_com_section (symbol->section))
    relocation = 0;
  else
    relocation = symbol->value;

  relocation += symbol->section->output_section->vma;
  relocation += symbol->section->output_offset;
  relocation += reloc_entry->addend;

  if (relocation & 0x8000)
    reloc_entry->addend += 0x10000;

  return bfd_reloc_continue;
}

static reloc_howto_type mips_howto_table_ext[] = {
  {MIPS_RELOC_32,      0, 2, 32, false, 0,  complain_overflow_bitfield, 0,
	"32",       false, 0, 0xffffffff, false},
  {MIPS_RELOC_JMP,     2, 2, 26, false, 0, complain_overflow_dont,
	mips_fix_jmp_addr,
	"MIPS_JMP", false, 0, 0x03ffffff, false},
  {MIPS_RELOC_WDISP16, 2, 2, 16, true,  0, complain_overflow_signed, 0,
	"WDISP16",  false, 0, 0x0000ffff, false},
  {MIPS_RELOC_HI16,   16, 2, 16, false, 0, complain_overflow_bitfield, 0,
	"HI16",     false, 0, 0x0000ffff, false},
  {MIPS_RELOC_HI16_S, 16, 2, 16, false, 0, complain_overflow_bitfield,
        mips_fix_hi16_s,
        "HI16_S",   false, 0, 0x0000ffff, false},
  {MIPS_RELOC_LO16,    0, 2, 16, false, 0, complain_overflow_dont, 0,
	"LO16",     false, 0, 0x0000ffff, false},
};

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

  if (bfd_get_arch (abfd) != bfd_arch_mips)
    return 0;

  switch (code)
    {
    case BFD_RELOC_CTOR:
    case BFD_RELOC_32:
      return (&mips_howto_table_ext[MIPS_RELOC_32]);
    case BFD_RELOC_MIPS_JMP:
      return (&mips_howto_table_ext[MIPS_RELOC_JMP]);
    case BFD_RELOC_16_PCREL_S2:
      return (&mips_howto_table_ext[MIPS_RELOC_WDISP16]);
    case BFD_RELOC_HI16:
      return (&mips_howto_table_ext[MIPS_RELOC_HI16]);
    case BFD_RELOC_HI16_S:
      return (&mips_howto_table_ext[MIPS_RELOC_HI16_S]);
    case BFD_RELOC_LO16:
      return (&mips_howto_table_ext[MIPS_RELOC_LO16]);
    default:
      return 0;
    }
}

/* This is just like the standard aoutx.h version but we need to do our
   own mapping of external reloc type values to howto entries.  */
long
MY(canonicalize_reloc) (abfd, section, relptr, symbols)
      bfd *abfd;
      sec_ptr section;
      arelent **relptr;
      asymbol **symbols;
{
  arelent *tblptr = section->relocation;
  unsigned int count, c;
  extern reloc_howto_type NAME(aout,ext_howto_table)[];

  /* If we have already read in the relocation table, return the values.  */
  if (section->flags & SEC_CONSTRUCTOR)
    {
      arelent_chain *chain = section->constructor_chain;

      for (count = 0; count < section->reloc_count; count++)
	{
	  *relptr++ = &chain->relent;
	  chain = chain->next;
	}
      *relptr = 0;
      return section->reloc_count;
    }

  if (tblptr && section->reloc_count)
    {
      for (count = 0; count++ < section->reloc_count;)
	*relptr++ = tblptr++;
      *relptr = 0;
      return section->reloc_count;
    }

  if (!NAME(aout,slurp_reloc_table) (abfd, section, symbols))
    return -1;
  tblptr = section->relocation;

  /* fix up howto entries.  */
  for (count = 0; count++ < section->reloc_count;)
    {
      c = tblptr->howto - NAME(aout,ext_howto_table);
      tblptr->howto = &mips_howto_table_ext[c];

      *relptr++ = tblptr++;
    }
  *relptr = 0;
  return section->reloc_count;
}

static const struct aout_backend_data MY(backend_data) = {
  0,				/* zmagic contiguous */
  1,				/* text incl header */
  0,				/* entry is text address */
  0,				/* exec_hdr_flags */
  TARGET_PAGE_SIZE,			/* text vma */
  MY_set_sizes,
  0,				/* text size includes exec header */
  0,				/* add_dynamic_symbols */
  0,				/* add_one_symbol */
  0,				/* link_dynamic_object */
  0,				/* write_dynamic_symbol */
  0,				/* check_dynamic_reloc */
  0				/* finish_dynamic_link */
};

extern const bfd_target aout_mips_big_vec;

const bfd_target aout_mips_little_vec =
  {
    "a.out-mips-little",		/* name */
    bfd_target_aout_flavour,
    BFD_ENDIAN_LITTLE,		/* target byte order (little) */
    BFD_ENDIAN_LITTLE,		/* target headers byte order (little) */
    (HAS_RELOC | EXEC_P |		/* object flags */
     HAS_LINENO | HAS_DEBUG |
     HAS_SYMS | HAS_LOCALS | WP_TEXT | D_PAGED),
    (SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD | SEC_RELOC | SEC_CODE | SEC_DATA),
    MY_symbol_leading_char,
    ' ',				/* 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_getl64, bfd_getl_signed_64, bfd_putl64,
    bfd_getl32, bfd_getl_signed_32, bfd_putl32,
    bfd_getl16, bfd_getl_signed_16, bfd_putl16, /* hdrs */
    {_bfd_dummy_target, MY_object_p, /* bfd_check_format */
     bfd_generic_archive_p, MY_core_file_p},
    {bfd_false, MY_mkobject,	/* bfd_set_format */
     _bfd_generic_mkarchive, bfd_false},
    {bfd_false, MY_write_object_contents, /* bfd_write_contents */
     _bfd_write_archive_contents, bfd_false},

    BFD_JUMP_TABLE_GENERIC (MY),
    BFD_JUMP_TABLE_COPY (MY),
    BFD_JUMP_TABLE_CORE (MY),
    BFD_JUMP_TABLE_ARCHIVE (MY),
    BFD_JUMP_TABLE_SYMBOLS (MY),
    BFD_JUMP_TABLE_RELOCS (MY),
    BFD_JUMP_TABLE_WRITE (MY),
    BFD_JUMP_TABLE_LINK (MY),
    BFD_JUMP_TABLE_DYNAMIC (_bfd_nodynamic),

    & aout_mips_big_vec,

    (PTR) MY_backend_data
  };

const bfd_target aout_mips_big_vec =
  {
    "a.out-mips-big",		/* name */
    bfd_target_aout_flavour,
    BFD_ENDIAN_BIG,		/* target byte order (big) */
    BFD_ENDIAN_BIG,		/* target headers byte order (big) */
    (HAS_RELOC | EXEC_P |		/* object flags */
     HAS_LINENO | HAS_DEBUG |
     HAS_SYMS | HAS_LOCALS | WP_TEXT | D_PAGED),
    (SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD | SEC_RELOC | SEC_CODE | SEC_DATA),
    MY_symbol_leading_char,
    ' ',				/* ar_pad_char */
    15,				/* ar_max_namelen */
    bfd_getb64, bfd_getb_signed_64, bfd_putb64,
    bfd_getb32, bfd_getb_signed_32, bfd_putb32,
    bfd_getb16, bfd_getb_signed_16, bfd_putb16, /* 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, MY_object_p, /* bfd_check_format */
     bfd_generic_archive_p, MY_core_file_p},
    {bfd_false, MY_mkobject,	/* bfd_set_format */
     _bfd_generic_mkarchive, bfd_false},
    {bfd_false, MY_write_object_contents, /* bfd_write_contents */
     _bfd_write_archive_contents, bfd_false},

    BFD_JUMP_TABLE_GENERIC (MY),
    BFD_JUMP_TABLE_COPY (MY),
    BFD_JUMP_TABLE_CORE (MY),
    BFD_JUMP_TABLE_ARCHIVE (MY),
    BFD_JUMP_TABLE_SYMBOLS (MY),
    BFD_JUMP_TABLE_RELOCS (MY),
    BFD_JUMP_TABLE_WRITE (MY),
    BFD_JUMP_TABLE_LINK (MY),
    BFD_JUMP_TABLE_DYNAMIC (_bfd_nodynamic),

    & aout_mips_little_vec,

    (PTR) MY_backend_data
  };
