/* Support for 32-bit SPARC NLM (NetWare Loadable Module)
   Copyright 1993, 1994, 2000, 2001 Free Software Foundation, Inc.

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

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

#define ARCH_SIZE 32

#include "nlm/sparc32-ext.h"
#define Nlm_External_Fixed_Header	Nlm32_sparc_External_Fixed_Header

#include "libnlm.h"

static boolean nlm_sparc_read_reloc
  PARAMS ((bfd *, nlmNAME(symbol_type) *, asection **, arelent *));
static boolean nlm_sparc_write_reloc
  PARAMS ((bfd *, asection *, arelent *));
static boolean nlm_sparc_mangle_relocs
  PARAMS ((bfd *, asection *, PTR, bfd_vma, bfd_size_type));
static boolean nlm_sparc_read_import
  PARAMS ((bfd *, nlmNAME(symbol_type) *));
static boolean nlm_sparc_write_import
  PARAMS ((bfd *, asection *, arelent *));
static boolean nlm_sparc_write_external
  PARAMS ((bfd *, bfd_size_type, asymbol *, struct reloc_and_sec *));
static boolean nlm_sparc_write_export
  PARAMS ((bfd *, asymbol *, bfd_vma));

enum reloc_type
  {
    R_SPARC_NONE = 0,
    R_SPARC_8,		R_SPARC_16,		R_SPARC_32,
    R_SPARC_DISP8,	R_SPARC_DISP16,		R_SPARC_DISP32,
    R_SPARC_WDISP30,	R_SPARC_WDISP22,
    R_SPARC_HI22,	R_SPARC_22,
    R_SPARC_13,		R_SPARC_LO10,
    R_SPARC_GOT10,	R_SPARC_GOT13,		R_SPARC_GOT22,
    R_SPARC_PC10,	R_SPARC_PC22,
    R_SPARC_WPLT30,
    R_SPARC_COPY,
    R_SPARC_GLOB_DAT,	R_SPARC_JMP_SLOT,
    R_SPARC_RELATIVE,
    R_SPARC_UA32,
    R_SPARC_max
  };

#if 0
static const char *const reloc_type_names[] =
  {
    "R_SPARC_NONE",
    "R_SPARC_8",		"R_SPARC_16",		"R_SPARC_32",
    "R_SPARC_DISP8",	"R_SPARC_DISP16",	"R_SPARC_DISP32",
    "R_SPARC_WDISP30",	"R_SPARC_WDISP22",
    "R_SPARC_HI22",	"R_SPARC_22",
    "R_SPARC_13",		"R_SPARC_LO10",
    "R_SPARC_GOT10",	"R_SPARC_GOT13",	"R_SPARC_GOT22",
    "R_SPARC_PC10",	"R_SPARC_PC22",
    "R_SPARC_WPLT30",
    "R_SPARC_COPY",
    "R_SPARC_GLOB_DAT",	"R_SPARC_JMP_SLOT",
    "R_SPARC_RELATIVE",
    "R_SPARC_UA32",
  };
#endif

static reloc_howto_type nlm32_sparc_howto_table[] =
  {
    HOWTO (R_SPARC_NONE,    0,0, 0,false,0,complain_overflow_dont,    0,"R_SPARC_NONE",    false,0,0x00000000,true),
    HOWTO (R_SPARC_8,       0,0, 8,false,0,complain_overflow_bitfield,0,"R_SPARC_8",       false,0,0x000000ff,true),
    HOWTO (R_SPARC_16,      0,1,16,false,0,complain_overflow_bitfield,0,"R_SPARC_16",      false,0,0x0000ffff,true),
    HOWTO (R_SPARC_32,      0,2,32,false,0,complain_overflow_bitfield,0,"R_SPARC_32",      false,0,0xffffffff,true),
    HOWTO (R_SPARC_DISP8,   0,0, 8,true, 0,complain_overflow_signed,  0,"R_SPARC_DISP8",   false,0,0x000000ff,true),
    HOWTO (R_SPARC_DISP16,  0,1,16,true, 0,complain_overflow_signed,  0,"R_SPARC_DISP16",  false,0,0x0000ffff,true),
    HOWTO (R_SPARC_DISP32,  0,2,32,true, 0,complain_overflow_signed,  0,"R_SPARC_DISP32",  false,0,0x00ffffff,true),
    HOWTO (R_SPARC_WDISP30, 2,2,30,true, 0,complain_overflow_signed,  0,"R_SPARC_WDISP30", false,0,0x3fffffff,true),
    HOWTO (R_SPARC_WDISP22, 2,2,22,true, 0,complain_overflow_signed,  0,"R_SPARC_WDISP22", false,0,0x003fffff,true),
    HOWTO (R_SPARC_HI22,   10,2,22,false,0,complain_overflow_dont,    0,"R_SPARC_HI22",    false,0,0x003fffff,true),
    HOWTO (R_SPARC_22,      0,2,22,false,0,complain_overflow_bitfield,0,"R_SPARC_22",      false,0,0x003fffff,true),
    HOWTO (R_SPARC_13,      0,2,13,false,0,complain_overflow_bitfield,0,"R_SPARC_13",      false,0,0x00001fff,true),
    HOWTO (R_SPARC_LO10,    0,2,10,false,0,complain_overflow_dont,    0,"R_SPARC_LO10",    false,0,0x000003ff,true),
    HOWTO (R_SPARC_GOT10,   0,2,10,false,0,complain_overflow_bitfield,0,"R_SPARC_GOT10",   false,0,0x000003ff,true),
    HOWTO (R_SPARC_GOT13,   0,2,13,false,0,complain_overflow_bitfield,0,"R_SPARC_GOT13",   false,0,0x00001fff,true),
    HOWTO (R_SPARC_GOT22,  10,2,22,false,0,complain_overflow_bitfield,0,"R_SPARC_GOT22",   false,0,0x003fffff,true),
    HOWTO (R_SPARC_PC10,    0,2,10,false,0,complain_overflow_bitfield,0,"R_SPARC_PC10",    false,0,0x000003ff,true),
    HOWTO (R_SPARC_PC22,    0,2,22,false,0,complain_overflow_bitfield,0,"R_SPARC_PC22",    false,0,0x003fffff,true),
    HOWTO (R_SPARC_WPLT30,  0,0,00,false,0,complain_overflow_dont,    0,"R_SPARC_WPLT30",  false,0,0x00000000,true),
    HOWTO (R_SPARC_COPY,    0,0,00,false,0,complain_overflow_dont,    0,"R_SPARC_COPY",    false,0,0x00000000,true),
    HOWTO (R_SPARC_GLOB_DAT,0,0,00,false,0,complain_overflow_dont,    0,"R_SPARC_GLOB_DAT",false,0,0x00000000,true),
    HOWTO (R_SPARC_JMP_SLOT,0,0,00,false,0,complain_overflow_dont,    0,"R_SPARC_JMP_SLOT",false,0,0x00000000,true),
    HOWTO (R_SPARC_RELATIVE,0,0,00,false,0,complain_overflow_dont,    0,"R_SPARC_RELATIVE",false,0,0x00000000,true),
    HOWTO (R_SPARC_UA32,    0,0,00,false,0,complain_overflow_dont,    0,"R_SPARC_UA32",    false,0,0x00000000,true),
};

/* Read a NetWare sparc reloc.  */

struct nlm32_sparc_reloc_ext
  {
    unsigned char offset[4];
    unsigned char addend[4];
    unsigned char type[1];
    unsigned char pad1[3];
  };

static boolean
nlm_sparc_read_reloc (abfd, sym, secp, rel)
     bfd *abfd;
     nlmNAME(symbol_type) *sym ATTRIBUTE_UNUSED;
     asection **secp;
     arelent *rel;
{
  bfd_vma val, addend;
  unsigned int index;
  unsigned int type;
  struct nlm32_sparc_reloc_ext tmp_reloc;
  asection *code_sec, *data_sec;

  if (bfd_bread (&tmp_reloc, (bfd_size_type) 12, abfd) != 12)
    return false;

  code_sec = bfd_get_section_by_name (abfd, NLM_CODE_NAME);
  data_sec = bfd_get_section_by_name (abfd, NLM_INITIALIZED_DATA_NAME);

  *secp = code_sec;

  val = bfd_get_32 (abfd, tmp_reloc.offset);
  addend = bfd_get_32 (abfd, tmp_reloc.addend);
  type = bfd_get_8 (abfd, tmp_reloc.type);

  rel->address = val;
  rel->addend = addend;
  rel->howto = NULL;

  for (index = 0;
       index < sizeof (nlm32_sparc_howto_table) / sizeof (reloc_howto_type);
       index++)
    if (nlm32_sparc_howto_table[index].type == type)
      {
	rel->howto = &nlm32_sparc_howto_table[index];
	break;
      }

#ifdef DEBUG
  fprintf (stderr, "%s:  address = %08lx, addend = %08lx, type = %d, howto = %08lx\n",
	   __FUNCTION__, rel->address, rel->addend, type, rel->howto);
#endif
  return true;

}

/* Write a NetWare sparc reloc.  */

static boolean
nlm_sparc_write_reloc (abfd, sec, rel)
     bfd *abfd;
     asection *sec;
     arelent *rel;
{
  bfd_vma val;
  struct nlm32_sparc_reloc_ext tmp_reloc;
  unsigned int index;
  int type = -1;
  reloc_howto_type *tmp;

  for (index = 0;
       index < sizeof (nlm32_sparc_howto_table) / sizeof (reloc_howto_type);
       index++)
    {
      tmp = &nlm32_sparc_howto_table[index];

      if (tmp->rightshift == rel->howto->rightshift
	  && tmp->size == rel->howto->size
	  && tmp->bitsize == rel->howto->bitsize
	  && tmp->pc_relative == rel->howto->pc_relative
	  && tmp->bitpos == rel->howto->bitpos
	  && tmp->src_mask == rel->howto->src_mask
	  && tmp->dst_mask == rel->howto->dst_mask)
	{
	  type = tmp->type;
	  break;
	}
    }
  if (type == -1)
    abort ();

  /* Netware wants a list of relocs for each address.
     Format is:
    	long	offset
    	long	addend
    	char	type
     That should be it.  */

  /* The value we write out is the offset into the appropriate
     segment.  This offset is the section vma, adjusted by the vma of
     the lowest section in that segment, plus the address of the
     relocation.  */
#if 0
  val = bfd_get_section_vma (abfd, (*rel->sym_ptr_ptr)->section) + rel->address;
#else
  val = bfd_get_section_vma (abfd, sec) + rel->address;
#endif

#ifdef DEBUG
  fprintf (stderr, "%s:  val = %08lx, addend = %08lx, type = %d\n",
	   __FUNCTION__, val, rel->addend, rel->howto->type);
#endif
  bfd_put_32 (abfd, val, tmp_reloc.offset);
  bfd_put_32 (abfd, rel->addend, tmp_reloc.addend);
  bfd_put_8 (abfd, (short) (rel->howto->type), tmp_reloc.type);

  if (bfd_bwrite (&tmp_reloc, (bfd_size_type) 12, abfd) != 12)
    return false;

  return true;
}

/* Mangle relocs for SPARC NetWare.  We can just use the standard
   SPARC relocs.  */

static boolean
nlm_sparc_mangle_relocs (abfd, sec, data, offset, count)
     bfd *abfd ATTRIBUTE_UNUSED;
     asection *sec ATTRIBUTE_UNUSED;
     PTR data ATTRIBUTE_UNUSED;
     bfd_vma offset ATTRIBUTE_UNUSED;
     bfd_size_type count ATTRIBUTE_UNUSED;
{
  return true;
}

/* Read a NetWare sparc import record.  */

static boolean
nlm_sparc_read_import (abfd, sym)
     bfd *abfd;
     nlmNAME(symbol_type) *sym;
{
  struct nlm_relent *nlm_relocs;	/* Relocation records for symbol.  */
  bfd_size_type rcount;			/* Number of relocs.  */
  bfd_byte temp[NLM_TARGET_LONG_SIZE];	/* Temporary 32-bit value.  */
  unsigned char symlength;		/* Length of symbol name.  */
  char *name;

  /* First, read in the number of relocation
     entries for this symbol.  */
  if (bfd_bread ((PTR) temp, (bfd_size_type) 4, abfd) != 4)
    return false;

  rcount = bfd_get_32 (abfd, temp);

  /* Next, read in the length of the symbol.  */

  if (bfd_bread ((PTR) &symlength, (bfd_size_type) sizeof (symlength), abfd)
      != sizeof (symlength))
    return false;
  sym -> symbol.the_bfd = abfd;
  name = bfd_alloc (abfd, (bfd_size_type) symlength + 1);
  if (name == NULL)
    return false;

  /* Then read in the symbol.  */

  if (bfd_bread (name, (bfd_size_type) symlength, abfd) != symlength)
    return false;
  name[symlength] = '\0';
  sym -> symbol.name = name;
  sym -> symbol.flags = 0;
  sym -> symbol.value = 0;
  sym -> symbol.section = bfd_und_section_ptr;

  /* Next, start reading in the relocs.  */

  nlm_relocs = ((struct nlm_relent *)
		bfd_alloc (abfd, rcount * sizeof (struct nlm_relent)));
  if (!nlm_relocs)
    return false;
  sym -> relocs = nlm_relocs;
  sym -> rcnt = 0;
  while (sym -> rcnt < rcount)
    {
      asection *section;

      if (nlm_sparc_read_reloc (abfd, sym, &section,
			      &nlm_relocs -> reloc)
	  == false)
	return false;
      nlm_relocs -> section = section;
      nlm_relocs++;
      sym -> rcnt++;
    }

  return true;
}

static boolean
nlm_sparc_write_import (abfd, sec, rel)
     bfd *abfd;
     asection *sec;
     arelent *rel;
{
  char temp[4];
  asection *code, *data, *bss, *symsec;
  bfd_vma base;

  code = bfd_get_section_by_name (abfd, NLM_CODE_NAME);
  data = bfd_get_section_by_name (abfd, NLM_INITIALIZED_DATA_NAME);
  bss = bfd_get_section_by_name (abfd, NLM_UNINITIALIZED_DATA_NAME);
  symsec = (*rel->sym_ptr_ptr)->section;

  if (symsec == code)
    base = 0;
  else if (symsec == data)
    base = bfd_section_size (abfd, code);
  else if (symsec == bss)
    base = bfd_section_size (abfd, code) + bfd_section_size (abfd, data);
  else
    base = 0;

#ifdef DEBUG
  fprintf (stderr, "%s:  <%x, 1>\n\t",
	   __FUNCTION__, base + (*rel->sym_ptr_ptr)->value);
#endif
  bfd_put_32 (abfd, base + (*rel->sym_ptr_ptr)->value, temp);
  if (bfd_bwrite ((PTR) temp, (bfd_size_type) 4, abfd) != 4)
    return false;
  bfd_put_32 (abfd, (bfd_vma) 1, temp);
  if (bfd_bwrite ((PTR) temp, (bfd_size_type) 4, abfd) != 4)
    return false;
  if (nlm_sparc_write_reloc (abfd, sec, rel) == false)
    return false;
  return true;
}

/* Write out an external reference.  */

static boolean
nlm_sparc_write_external (abfd, count, sym, relocs)
     bfd *abfd;
     bfd_size_type count;
     asymbol *sym;
     struct reloc_and_sec *relocs;
{
  unsigned int i;
  bfd_byte len;
  unsigned char temp[NLM_TARGET_LONG_SIZE];

  bfd_put_32 (abfd, count, temp);
  if (bfd_bwrite (temp, (bfd_size_type) sizeof (temp), abfd) != sizeof (temp))
    return false;

  len = strlen (sym->name);
  if ((bfd_bwrite (&len, (bfd_size_type) sizeof (bfd_byte), abfd)
       != sizeof (bfd_byte))
      || bfd_bwrite (sym->name, (bfd_size_type) len, abfd) != len)
    return false;

  for (i = 0; i < count; i++)
    {
      if (nlm_sparc_write_reloc (abfd, relocs[i].sec,
				 relocs[i].rel) == false)
	return false;
    }

  return true;
}

static boolean
nlm_sparc_write_export (abfd, sym, value)
     bfd *abfd;
     asymbol *sym;
     bfd_vma value;
{
  bfd_byte len;
  bfd_byte temp[4];

#ifdef DEBUG
  fprintf (stderr, "%s: <%x, %d, %s>\n",
	   __FUNCTION__, value, strlen (sym->name), sym->name);
#endif
  bfd_put_32 (abfd, value, temp);
  len = strlen (sym->name);

  if (bfd_bwrite (temp, (bfd_size_type) 4, abfd) != 4
      || bfd_bwrite (&len, (bfd_size_type) 1, abfd) != 1
      || bfd_bwrite (sym->name, (bfd_size_type) len, abfd) != len)
    return false;

  return true;
}

#undef nlm_swap_fixed_header_in
#undef nlm_swap_fixed_header_out

#include "nlmswap.h"

static const struct nlm_backend_data nlm32_sparc_backend =
  {
    "NetWare SPARC Module   \032",
    sizeof (Nlm32_sparc_External_Fixed_Header),
    0,	/* optional_prefix_size */
    bfd_arch_sparc,
    0,
    false,
    0,	/* backend_object_p */
    0,	/* write_prefix_func */
    nlm_sparc_read_reloc,
    nlm_sparc_mangle_relocs,
    nlm_sparc_read_import,
    nlm_sparc_write_import,
    0,	/* set_public_section */
    0,	/* get_public_offset */
    nlm_swap_fixed_header_in,
    nlm_swap_fixed_header_out,
    nlm_sparc_write_external,
    nlm_sparc_write_export
  };

#define TARGET_BIG_NAME		"nlm32-sparc"
#define TARGET_BIG_SYM		nlmNAME(sparc_vec)
#define TARGET_BACKEND_DATA	& nlm32_sparc_backend

#include "nlm-target.h"
