/* BFD back-end for oasys objects.
   Copyright 1990, 91, 92, 93, 94, 95, 96, 97, 98, 1999
   Free Software Foundation, Inc.
   Written by Steve Chamberlain of Cygnus Support, <sac@cygnus.com>.

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 UNDERSCORE_HACK 1
#include "bfd.h"
#include "sysdep.h"
#include <ctype.h>
#include "libbfd.h"
#include "oasys.h"
#include "liboasys.h"

/* XXX - FIXME.  offsetof belongs in the system-specific files in
   ../include/sys. */
/* Define offsetof for those systems which lack it */

#ifndef offsetof
#define offsetof(type, identifier) (size_t) &(((type *) 0)->identifier)
#endif

static boolean oasys_read_record PARAMS ((bfd *,
					  oasys_record_union_type *));
static boolean oasys_write_sections PARAMS ((bfd *));
static boolean oasys_write_record PARAMS ((bfd *,
					   oasys_record_enum_type,
					   oasys_record_union_type *,
					   size_t));
static boolean oasys_write_syms PARAMS ((bfd *));
static boolean oasys_write_header PARAMS ((bfd *));
static boolean oasys_write_end PARAMS ((bfd *));
static boolean oasys_write_data PARAMS ((bfd *));

/* Read in all the section data and relocation stuff too */
PROTO (static boolean, oasys_slurp_section_data, (bfd * CONST abfd));

static boolean
oasys_read_record (abfd, record)
     bfd *abfd;
     oasys_record_union_type *record;
{
  if (bfd_read ((PTR) record, 1, sizeof (record->header), abfd)
      != sizeof (record->header))
    return false;

  if ((size_t) record->header.length <= (size_t) sizeof (record->header))
    return true;
  if (bfd_read ((PTR) (((char *) record) + sizeof (record->header)),
		1, record->header.length - sizeof (record->header),
		abfd)
      != record->header.length - sizeof (record->header))
    return false;
  return true;
}
static size_t
oasys_string_length (record)
     oasys_record_union_type *record;
{
  return record->header.length
    - ((char *) record->symbol.name - (char *) record);
}

/*****************************************************************************/

/*

Slurp the symbol table by reading in all the records at the start file
till we get to the first section record.

We'll sort the symbolss into  two lists, defined and undefined. The
undefined symbols will be placed into the table according to their
refno.

We do this by placing all undefined symbols at the front of the table
moving in, and the defined symbols at the end of the table moving back.

*/

static boolean
oasys_slurp_symbol_table (abfd)
     bfd *CONST abfd;
{
  oasys_record_union_type record;
  oasys_data_type *data = OASYS_DATA (abfd);
  boolean loop = true;
  asymbol *dest_defined;
  asymbol *dest;
  char *string_ptr;


  if (data->symbols != (asymbol *) NULL)
    {
      return true;
    }
  /* Buy enough memory for all the symbols and all the names */
  data->symbols =
    (asymbol *) bfd_alloc (abfd, sizeof (asymbol) * abfd->symcount);
#ifdef UNDERSCORE_HACK
  /* buy 1 more char for each symbol to keep the underscore in*/
  data->strings = bfd_alloc (abfd, data->symbol_string_length +
			     abfd->symcount);
#else
  data->strings = bfd_alloc (abfd, data->symbol_string_length);
#endif
  if (!data->symbols || !data->strings)
    return false;

  dest_defined = data->symbols + abfd->symcount - 1;

  string_ptr = data->strings;
  if (bfd_seek (abfd, (file_ptr) 0, SEEK_SET) != 0)
    return false;
  while (loop)
    {

      if (! oasys_read_record (abfd, &record))
	return false;
      switch (record.header.type)
	{
	case oasys_record_is_header_enum:
	  break;
	case oasys_record_is_local_enum:
	case oasys_record_is_symbol_enum:
	  {
	    int flag = record.header.type == (int) oasys_record_is_local_enum ?
	    (BSF_LOCAL) : (BSF_GLOBAL | BSF_EXPORT);


	    size_t length = oasys_string_length (&record);
	    switch (record.symbol.relb & RELOCATION_TYPE_BITS)
	      {
	      case RELOCATION_TYPE_ABS:
		dest = dest_defined--;
		dest->section = bfd_abs_section_ptr;
		dest->flags = 0;

		break;
	      case RELOCATION_TYPE_REL:
		dest = dest_defined--;
		dest->section =
		  OASYS_DATA (abfd)->sections[record.symbol.relb &
					      RELOCATION_SECT_BITS];
		if (record.header.type == (int) oasys_record_is_local_enum)
		  {
		    dest->flags = BSF_LOCAL;
		    if (dest->section == (asection *) (~0))
		      {
			/* It seems that sometimes internal symbols are tied up, but
		       still get output, even though there is no
		       section */
			dest->section = 0;
		      }
		  }
		else
		  {

		    dest->flags = flag;
		  }
		break;
	      case RELOCATION_TYPE_UND:
		dest = data->symbols + bfd_h_get_16 (abfd, record.symbol.refno);
		dest->section = bfd_und_section_ptr;
		break;
	      case RELOCATION_TYPE_COM:
		dest = dest_defined--;
		dest->name = string_ptr;
		dest->the_bfd = abfd;

		dest->section = bfd_com_section_ptr;

		break;
	      default:
		dest = dest_defined--;
		BFD_ASSERT (0);
		break;
	      }
	    dest->name = string_ptr;
	    dest->the_bfd = abfd;
	    dest->udata.p = (PTR) NULL;
	    dest->value = bfd_h_get_32 (abfd, record.symbol.value);

#ifdef UNDERSCORE_HACK
	    if (record.symbol.name[0] != '_')
	      {
		string_ptr[0] = '_';
		string_ptr++;
	      }
#endif
	    memcpy (string_ptr, record.symbol.name, length);


	    string_ptr[length] = 0;
	    string_ptr += length + 1;
	  }
	  break;
	default:
	  loop = false;
	}
    }
  return true;
}

static long
oasys_get_symtab_upper_bound (abfd)
     bfd *CONST abfd;
{
  if (! oasys_slurp_symbol_table (abfd))
    return -1;

  return (abfd->symcount + 1) * (sizeof (oasys_symbol_type *));
}

/*
*/

extern const bfd_target oasys_vec;

long
oasys_get_symtab (abfd, location)
     bfd *abfd;
     asymbol **location;
{
  asymbol *symbase;
  unsigned int counter;
  if (oasys_slurp_symbol_table (abfd) == false)
    {
      return -1;
    }
  symbase = OASYS_DATA (abfd)->symbols;
  for (counter = 0; counter < abfd->symcount; counter++)
    {
      *(location++) = symbase++;
    }
  *location = 0;
  return abfd->symcount;
}

/***********************************************************************
*  archive stuff
*/

static const bfd_target *
oasys_archive_p (abfd)
     bfd *abfd;
{
  oasys_archive_header_type header;
  oasys_extarchive_header_type header_ext;
  unsigned int i;
  file_ptr filepos;

  if (bfd_seek (abfd, (file_ptr) 0, false) != 0
      || (bfd_read ((PTR) & header_ext, 1, sizeof (header_ext), abfd)
	  != sizeof (header_ext)))
    {
      if (bfd_get_error () != bfd_error_system_call)
	bfd_set_error (bfd_error_wrong_format);
      return NULL;
    }

  header.version = bfd_h_get_32 (abfd, header_ext.version);
  header.mod_count = bfd_h_get_32 (abfd, header_ext.mod_count);
  header.mod_tbl_offset = bfd_h_get_32 (abfd, header_ext.mod_tbl_offset);
  header.sym_tbl_size = bfd_h_get_32 (abfd, header_ext.sym_tbl_size);
  header.sym_count = bfd_h_get_32 (abfd, header_ext.sym_count);
  header.sym_tbl_offset = bfd_h_get_32 (abfd, header_ext.sym_tbl_offset);
  header.xref_count = bfd_h_get_32 (abfd, header_ext.xref_count);
  header.xref_lst_offset = bfd_h_get_32 (abfd, header_ext.xref_lst_offset);

  /*
    There isn't a magic number in an Oasys archive, so the best we
    can do to verify reasnableness is to make sure that the values in
    the header are too weird
    */

  if (header.version > 10000 ||
      header.mod_count > 10000 ||
      header.sym_count > 100000 ||
      header.xref_count > 100000)
    return (const bfd_target *) NULL;

  /*
    That all worked, let's buy the space for the header and read in
    the headers.
    */
  {
    oasys_ar_data_type *ar =
    (oasys_ar_data_type *) bfd_alloc (abfd, sizeof (oasys_ar_data_type));

    oasys_module_info_type *module =
    (oasys_module_info_type *)
    bfd_alloc (abfd, sizeof (oasys_module_info_type) * header.mod_count);
    oasys_module_table_type record;

    if (!ar || !module)
      return NULL;

    abfd->tdata.oasys_ar_data = ar;
    ar->module = module;
    ar->module_count = header.mod_count;

    filepos = header.mod_tbl_offset;
    for (i = 0; i < header.mod_count; i++)
      {
	if (bfd_seek (abfd, filepos, SEEK_SET) != 0)
	  return NULL;

	/* There are two ways of specifying the archive header */

	if (0)
	  {
	    oasys_extmodule_table_type_a_type record_ext;
	    if (bfd_read ((PTR) & record_ext, 1, sizeof (record_ext), abfd)
		!= sizeof (record_ext))
	      return NULL;

	    record.mod_size = bfd_h_get_32 (abfd, record_ext.mod_size);
	    record.file_offset = bfd_h_get_32 (abfd, record_ext.file_offset);

	    record.dep_count = bfd_h_get_32 (abfd, record_ext.dep_count);
	    record.depee_count = bfd_h_get_32 (abfd, record_ext.depee_count);
	    record.sect_count = bfd_h_get_32 (abfd, record_ext.sect_count);

	    module[i].name = bfd_alloc (abfd, 33);
	    if (!module[i].name)
	      return NULL;

	    memcpy (module[i].name, record_ext.mod_name, 33);
	    filepos +=
	      sizeof (record_ext) +
	      record.dep_count * 4 +
	      record.depee_count * 4 +
	      record.sect_count * 8 + 187;
	  }
	else
	  {
	    oasys_extmodule_table_type_b_type record_ext;
	    if (bfd_read ((PTR) & record_ext, 1, sizeof (record_ext), abfd)
		!= sizeof (record_ext))
	      return NULL;

	    record.mod_size = bfd_h_get_32 (abfd, record_ext.mod_size);
	    record.file_offset = bfd_h_get_32 (abfd, record_ext.file_offset);

	    record.dep_count = bfd_h_get_32 (abfd, record_ext.dep_count);
	    record.depee_count = bfd_h_get_32 (abfd, record_ext.depee_count);
	    record.sect_count = bfd_h_get_32 (abfd, record_ext.sect_count);
	    record.module_name_size = bfd_h_get_32 (abfd, record_ext.mod_name_length);

	    module[i].name = bfd_alloc (abfd, record.module_name_size + 1);
	    if (!module[i].name)
	      return NULL;
	    if (bfd_read ((PTR) module[i].name, 1, record.module_name_size,
			  abfd)
		!= record.module_name_size)
	      return NULL;
	    module[i].name[record.module_name_size] = 0;
	    filepos +=
	      sizeof (record_ext) +
	      record.dep_count * 4 +
	      record.module_name_size + 1;

	  }


	module[i].size = record.mod_size;
	module[i].pos = record.file_offset;
	module[i].abfd = 0;
      }

  }
  return abfd->xvec;
}

static boolean
oasys_mkobject (abfd)
     bfd *abfd;
{

  abfd->tdata.oasys_obj_data = (oasys_data_type *) bfd_alloc (abfd, sizeof (oasys_data_type));
  return abfd->tdata.oasys_obj_data ? true : false;
}

#define MAX_SECS 16
static const bfd_target *
oasys_object_p (abfd)
     bfd *abfd;
{
  oasys_data_type *oasys;
  oasys_data_type *save = OASYS_DATA (abfd);
  boolean loop = true;
  boolean had_usefull = false;

  abfd->tdata.oasys_obj_data = 0;
  oasys_mkobject (abfd);
  oasys = OASYS_DATA (abfd);
  memset ((PTR) oasys->sections, 0xff, sizeof (oasys->sections));

  /* Point to the start of the file */
  if (bfd_seek (abfd, (file_ptr) 0, SEEK_SET) != 0)
    goto fail;
  oasys->symbol_string_length = 0;
  /* Inspect the records, but only keep the section info -
     remember the size of the symbols
     */
  oasys->first_data_record = 0;
  while (loop)
    {
      oasys_record_union_type record;
      if (! oasys_read_record (abfd, &record))
	goto fail;
      if ((size_t) record.header.length < (size_t) sizeof (record.header))
	goto fail;


      switch ((oasys_record_enum_type) (record.header.type))
	{
	case oasys_record_is_header_enum:
	  had_usefull = true;
	  break;
	case oasys_record_is_symbol_enum:
	case oasys_record_is_local_enum:
	  /* Count symbols and remember their size for a future malloc   */
	  abfd->symcount++;
	  oasys->symbol_string_length += 1 + oasys_string_length (&record);
	  had_usefull = true;
	  break;
	case oasys_record_is_section_enum:
	  {
	    asection *s;
	    char *buffer;
	    unsigned int section_number;
	    if (record.section.header.length != sizeof (record.section))
	      {
		goto fail;
	      }
	    buffer = bfd_alloc (abfd, 3);
	    if (!buffer)
	      goto fail;
	    section_number = record.section.relb & RELOCATION_SECT_BITS;
	    sprintf (buffer, "%u", section_number);
	    s = bfd_make_section (abfd, buffer);
	    oasys->sections[section_number] = s;
	    switch (record.section.relb & RELOCATION_TYPE_BITS)
	      {
	      case RELOCATION_TYPE_ABS:
	      case RELOCATION_TYPE_REL:
		break;
	      case RELOCATION_TYPE_UND:
	      case RELOCATION_TYPE_COM:
		BFD_FAIL ();
	      }

	    s->_raw_size = bfd_h_get_32 (abfd, record.section.value);
	    s->vma = bfd_h_get_32 (abfd, record.section.vma);
	    s->flags = 0;
	    had_usefull = true;
	  }
	  break;
	case oasys_record_is_data_enum:
	  oasys->first_data_record = bfd_tell (abfd) - record.header.length;
	case oasys_record_is_debug_enum:
	case oasys_record_is_module_enum:
	case oasys_record_is_named_section_enum:
	case oasys_record_is_end_enum:
	  if (had_usefull == false)
	    goto fail;
	  loop = false;
	  break;
	default:
	  goto fail;
	}
    }
  oasys->symbols = (asymbol *) NULL;
  /*
    Oasys support several architectures, but I can't see a simple way
    to discover which one is in a particular file - we'll guess
    */
  bfd_default_set_arch_mach (abfd, bfd_arch_m68k, 0);
  if (abfd->symcount != 0)
    {
      abfd->flags |= HAS_SYMS;
    }

  /*
    We don't know if a section has data until we've read it..
    */

  oasys_slurp_section_data (abfd);


  return abfd->xvec;

fail:
  (void) bfd_release (abfd, oasys);
  abfd->tdata.oasys_obj_data = save;
  return (const bfd_target *) NULL;
}


static void
oasys_get_symbol_info (ignore_abfd, symbol, ret)
     bfd *ignore_abfd ATTRIBUTE_UNUSED;
     asymbol *symbol;
     symbol_info *ret;
{
  bfd_symbol_info (symbol, ret);
  if (!symbol->section)
    ret->type = (symbol->flags & BSF_LOCAL) ? 'a' : 'A';
}

static void
oasys_print_symbol (ignore_abfd, afile, symbol, how)
     bfd *ignore_abfd ATTRIBUTE_UNUSED;
     PTR afile;
     asymbol *symbol;
     bfd_print_symbol_type how;
{
  FILE *file = (FILE *) afile;

  switch (how)
    {
    case bfd_print_symbol_name:
    case bfd_print_symbol_more:
      fprintf (file, "%s", symbol->name);
      break;
    case bfd_print_symbol_all:
      {
	CONST char *section_name = symbol->section == (asection *) NULL ?
	(CONST char *) "*abs" : symbol->section->name;

	bfd_print_symbol_vandf ((PTR) file, symbol);

	fprintf (file, " %-5s %s",
		 section_name,
		 symbol->name);
      }
      break;
    }
}
/*
 The howto table is build using the top two bits of a reloc byte to
 index into it. The bits are PCREL,WORD/LONG
*/
static reloc_howto_type howto_table[] =
{

  HOWTO (0, 0, 1, 16, false, 0, complain_overflow_bitfield, 0, "abs16", true, 0x0000ffff, 0x0000ffff, false),
  HOWTO (0, 0, 2, 32, false, 0, complain_overflow_bitfield, 0, "abs32", true, 0xffffffff, 0xffffffff, false),
  HOWTO (0, 0, 1, 16, true, 0, complain_overflow_signed, 0, "pcrel16", true, 0x0000ffff, 0x0000ffff, false),
  HOWTO (0, 0, 2, 32, true, 0, complain_overflow_signed, 0, "pcrel32", true, 0xffffffff, 0xffffffff, false)
};

/* Read in all the section data and relocation stuff too */
static boolean
oasys_slurp_section_data (abfd)
     bfd *CONST abfd;
{
  oasys_record_union_type record;
  oasys_data_type *data = OASYS_DATA (abfd);
  boolean loop = true;

  oasys_per_section_type *per;

  asection *s;

  /* See if the data has been slurped already .. */
  for (s = abfd->sections; s != (asection *) NULL; s = s->next)
    {
      per = oasys_per_section (s);
      if (per->initialized == true)
	return true;
    }

  if (data->first_data_record == 0)
    return true;

  if (bfd_seek (abfd, data->first_data_record, SEEK_SET) != 0)
    return false;
  while (loop)
    {
      if (! oasys_read_record (abfd, &record))
	return false;
      switch (record.header.type)
	{
	case oasys_record_is_header_enum:
	  break;
	case oasys_record_is_data_enum:
	  {

	    bfd_byte *src = record.data.data;
	    bfd_byte *end_src = ((bfd_byte *) & record) + record.header.length;
	    bfd_byte *dst_ptr;
	    bfd_byte *dst_base_ptr;
	    unsigned int relbit;
	    unsigned int count;
	    asection *section =
	    data->sections[record.data.relb & RELOCATION_SECT_BITS];
	    bfd_vma dst_offset;

	    per = oasys_per_section (section);

	    if (per->initialized == false)
	      {
		per->data = (bfd_byte *) bfd_zalloc (abfd, section->_raw_size);
		if (!per->data)
		  return false;
		per->reloc_tail_ptr = (oasys_reloc_type **) & (section->relocation);
		per->had_vma = false;
		per->initialized = true;
		section->reloc_count = 0;
		section->flags = SEC_ALLOC;
	      }

	    dst_offset = bfd_h_get_32 (abfd, record.data.addr);
	    if (per->had_vma == false)
	      {
		/* Take the first vma we see as the base */
		section->vma = dst_offset;
		per->had_vma = true;
	      }

	    dst_offset -= section->vma;

	    dst_base_ptr = oasys_per_section (section)->data;
	    dst_ptr = oasys_per_section (section)->data +
	      dst_offset;

	    if (src < end_src)
	      {
		section->flags |= SEC_LOAD | SEC_HAS_CONTENTS;
	      }
	    while (src < end_src)
	      {
		unsigned char mod_byte = *src++;
		size_t gap = end_src - src;

		count = 8;
		if (mod_byte == 0 && gap >= 8)
		  {
		    dst_ptr[0] = src[0];
		    dst_ptr[1] = src[1];
		    dst_ptr[2] = src[2];
		    dst_ptr[3] = src[3];
		    dst_ptr[4] = src[4];
		    dst_ptr[5] = src[5];
		    dst_ptr[6] = src[6];
		    dst_ptr[7] = src[7];
		    dst_ptr += 8;
		    src += 8;
		  }
		else
		  {
		    for (relbit = 1; count-- != 0 && src < end_src; relbit <<= 1)
		      {
			if (relbit & mod_byte)
			  {
			    unsigned char reloc = *src;
			    /* This item needs to be relocated */
			    switch (reloc & RELOCATION_TYPE_BITS)
			      {
			      case RELOCATION_TYPE_ABS:

				break;

			      case RELOCATION_TYPE_REL:
				{
				  /* Relocate the item relative to the section */
				  oasys_reloc_type *r =
				  (oasys_reloc_type *)
				  bfd_alloc (abfd,
					     sizeof (oasys_reloc_type));
				  if (!r)
				    return false;
				  *(per->reloc_tail_ptr) = r;
				  per->reloc_tail_ptr = &r->next;
				  r->next = (oasys_reloc_type *) NULL;
				  /* Reference to undefined symbol */
				  src++;
				  /* There is no symbol */
				  r->symbol = 0;
				  /* Work out the howto */
				  abort ();
#if 0
				  r->relent.section =
				    data->sections[reloc &
						   RELOCATION_SECT_BITS];

				  r->relent.addend = -
				    r->relent.section->vma;
#endif
				  r->relent.address = dst_ptr - dst_base_ptr;
				  r->relent.howto = &howto_table[reloc >> 6];
				  r->relent.sym_ptr_ptr = (asymbol **) NULL;
				  section->reloc_count++;

				  /* Fake up the data to look like it's got the -ve pc in it, this makes
				       it much easier to convert into other formats. This is done by
				       hitting the addend.
				       */
				  if (r->relent.howto->pc_relative == true)
				    {
				      r->relent.addend -= dst_ptr - dst_base_ptr;
				    }


				}
				break;


			      case RELOCATION_TYPE_UND:
				{
				  oasys_reloc_type *r =
				  (oasys_reloc_type *)
				  bfd_alloc (abfd,
					     sizeof (oasys_reloc_type));
				  if (!r)
				    return false;
				  *(per->reloc_tail_ptr) = r;
				  per->reloc_tail_ptr = &r->next;
				  r->next = (oasys_reloc_type *) NULL;
				  /* Reference to undefined symbol */
				  src++;
				  /* Get symbol number */
				  r->symbol = (src[0] << 8) | src[1];
				  /* Work out the howto */
				  abort ();

#if 0
				  r->relent.section = (asection
						       *) NULL;
#endif
				  r->relent.addend = 0;
				  r->relent.address = dst_ptr - dst_base_ptr;
				  r->relent.howto = &howto_table[reloc >> 6];
				  r->relent.sym_ptr_ptr = (asymbol **) NULL;
				  section->reloc_count++;

				  src += 2;
				  /* Fake up the data to look like it's got the -ve pc in it, this makes
				       it much easier to convert into other formats. This is done by
				       hitting the addend.
				       */
				  if (r->relent.howto->pc_relative == true)
				    {
				      r->relent.addend -= dst_ptr - dst_base_ptr;
				    }



				}
				break;
			      case RELOCATION_TYPE_COM:
				BFD_FAIL ();
			      }
			  }
			*dst_ptr++ = *src++;
		      }
		  }
	      }
	  }
	  break;
	case oasys_record_is_local_enum:
	case oasys_record_is_symbol_enum:
	case oasys_record_is_section_enum:
	  break;
	default:
	  loop = false;
	}
    }

  return true;

}

static boolean
oasys_new_section_hook (abfd, newsect)
     bfd *abfd;
     asection *newsect;
{
  newsect->used_by_bfd = (PTR)
    bfd_alloc (abfd, sizeof (oasys_per_section_type));
  if (!newsect->used_by_bfd)
    return false;
  oasys_per_section (newsect)->data = (bfd_byte *) NULL;
  oasys_per_section (newsect)->section = newsect;
  oasys_per_section (newsect)->offset = 0;
  oasys_per_section (newsect)->initialized = false;
  newsect->alignment_power = 1;
  /* Turn the section string into an index */

  sscanf (newsect->name, "%u", &newsect->target_index);

  return true;
}


static long
oasys_get_reloc_upper_bound (abfd, asect)
     bfd *abfd;
     sec_ptr asect;
{
  if (! oasys_slurp_section_data (abfd))
    return -1;
  return (asect->reloc_count + 1) * sizeof (arelent *);
}

static boolean
oasys_get_section_contents (abfd, section, location, offset, count)
     bfd *abfd;
     sec_ptr section;
     PTR location;
     file_ptr offset;
     bfd_size_type count;
{
  oasys_per_section_type *p = (oasys_per_section_type *) section->used_by_bfd;
  oasys_slurp_section_data (abfd);
  if (p->initialized == false)
    {
      (void) memset (location, 0, (int) count);
    }
  else
    {
      (void) memcpy (location, (PTR) (p->data + offset), (int) count);
    }
  return true;
}


long
oasys_canonicalize_reloc (ignore_abfd, section, relptr, symbols)
     bfd *ignore_abfd ATTRIBUTE_UNUSED;
     sec_ptr section;
     arelent **relptr;
     asymbol **symbols ATTRIBUTE_UNUSED;
{
  unsigned int reloc_count = 0;
  oasys_reloc_type *src = (oasys_reloc_type *) (section->relocation);
  while (src != (oasys_reloc_type *) NULL)
    {
      abort ();

#if 0
      if (src->relent.section == (asection *) NULL)
	{
	  src->relent.sym_ptr_ptr = symbols + src->symbol;
	}
#endif

      *relptr++ = &src->relent;
      src = src->next;
      reloc_count++;
    }
  *relptr = (arelent *) NULL;
  return section->reloc_count = reloc_count;
}




/* Writing */


/* Calculate the checksum and write one record */
static boolean
oasys_write_record (abfd, type, record, size)
     bfd *abfd;
     oasys_record_enum_type type;
     oasys_record_union_type *record;
     size_t size;
{
  int checksum;
  size_t i;
  unsigned char *ptr;

  record->header.length = size;
  record->header.type = (int) type;
  record->header.check_sum = 0;
  record->header.fill = 0;
  ptr = (unsigned char *) &record->pad[0];
  checksum = 0;
  for (i = 0; i < size; i++)
    {
      checksum += *ptr++;
    }
  record->header.check_sum = 0xff & (-checksum);
  if (bfd_write ((PTR) record, 1, size, abfd) != size)
    return false;
  return true;
}


/* Write out all the symbols */
static boolean
oasys_write_syms (abfd)
     bfd *abfd;
{
  unsigned int count;
  asymbol **generic = bfd_get_outsymbols (abfd);
  unsigned int index = 0;
  for (count = 0; count < bfd_get_symcount (abfd); count++)
    {

      oasys_symbol_record_type symbol;
      asymbol *CONST g = generic[count];

      CONST char *src = g->name;
      char *dst = symbol.name;
      unsigned int l = 0;

      if (bfd_is_com_section (g->section))
	{
	  symbol.relb = RELOCATION_TYPE_COM;
	  bfd_h_put_16 (abfd, index, symbol.refno);
	  index++;
	}
      else if (bfd_is_abs_section (g->section))
	{
	  symbol.relb = RELOCATION_TYPE_ABS;
	  bfd_h_put_16 (abfd, 0, symbol.refno);

	}
      else if (bfd_is_und_section (g->section))
	{
	  symbol.relb = RELOCATION_TYPE_UND;
	  bfd_h_put_16 (abfd, index, symbol.refno);
	  /* Overload the value field with the output index number */
	  index++;
	}
      else if (g->flags & BSF_DEBUGGING)
	{
	  /* throw it away */
	  continue;
	}
      else
	{
	  if (g->section == (asection *) NULL)
	    {
	      /* Sometime, the oasys tools give out a symbol with illegal
	   bits in it, we'll output it in the same broken way */

	      symbol.relb = RELOCATION_TYPE_REL | 0;
	    }
	  else
	    {
	      symbol.relb = RELOCATION_TYPE_REL | g->section->output_section->target_index;
	    }
	  bfd_h_put_16 (abfd, 0, symbol.refno);
	}
#ifdef UNDERSCORE_HACK
      if (src[l] == '_')
	dst[l++] = '.';
#endif
      while (src[l])
	{
	  dst[l] = src[l];
	  l++;
	}

      bfd_h_put_32 (abfd, g->value, symbol.value);


      if (g->flags & BSF_LOCAL)
	{
	  if (! oasys_write_record (abfd,
				    oasys_record_is_local_enum,
				    (oasys_record_union_type *) & symbol,
				    offsetof (oasys_symbol_record_type,
					      name[0]) + l))
	    return false;
	}
      else
	{
	  if (! oasys_write_record (abfd,
				    oasys_record_is_symbol_enum,
				    (oasys_record_union_type *) & symbol,
				    offsetof (oasys_symbol_record_type,
					      name[0]) + l))
	    return false;
	}
      g->value = index - 1;
    }

  return true;
}


 /* Write a section header for each section */
static boolean
oasys_write_sections (abfd)
     bfd *abfd;
{
  asection *s;
  static oasys_section_record_type out;

  for (s = abfd->sections; s != (asection *) NULL; s = s->next)
    {
      if (!isdigit ((unsigned char) s->name[0]))
	{
	  (*_bfd_error_handler)
	    (_("%s: can not represent section `%s' in oasys"),
	     bfd_get_filename (abfd), s->name);
	  bfd_set_error (bfd_error_nonrepresentable_section);
	  return false;
	}
      out.relb = RELOCATION_TYPE_REL | s->target_index;
      bfd_h_put_32 (abfd, s->_cooked_size, out.value);
      bfd_h_put_32 (abfd, s->vma, out.vma);

      if (! oasys_write_record (abfd,
				oasys_record_is_section_enum,
				(oasys_record_union_type *) & out,
				sizeof (out)))
	return false;
    }
  return true;
}

static boolean
oasys_write_header (abfd)
     bfd *abfd;
{
  /* Create and write the header */
  oasys_header_record_type r;
  size_t length = strlen (abfd->filename);
  if (length > (size_t) sizeof (r.module_name))
    {
      length = sizeof (r.module_name);
    }

  (void) memcpy (r.module_name,
		 abfd->filename,
		 length);
  (void) memset (r.module_name + length,
		 ' ',
		 sizeof (r.module_name) - length);

  r.version_number = OASYS_VERSION_NUMBER;
  r.rev_number = OASYS_REV_NUMBER;
  if (! oasys_write_record (abfd,
			    oasys_record_is_header_enum,
			    (oasys_record_union_type *) & r,
			    offsetof (oasys_header_record_type,
				      description[0])))
    return false;

  return true;
}

static boolean
oasys_write_end (abfd)
     bfd *abfd;
{
  oasys_end_record_type end;
  unsigned char null = 0;
  end.relb = RELOCATION_TYPE_ABS;
  bfd_h_put_32 (abfd, abfd->start_address, end.entry);
  bfd_h_put_16 (abfd, 0, end.fill);
  end.zero = 0;
  if (! oasys_write_record (abfd,
			    oasys_record_is_end_enum,
			    (oasys_record_union_type *) & end,
			    sizeof (end)))
    return false;
  if (bfd_write ((PTR) & null, 1, 1, abfd) != 1)
    return false;
  return true;
}

static int
comp (ap, bp)
     CONST PTR ap;
     CONST PTR bp;
{
  arelent *a = *((arelent **) ap);
  arelent *b = *((arelent **) bp);
  return a->address - b->address;
}

/*
 Writing data..

*/
static boolean
oasys_write_data (abfd)
     bfd *abfd;
{
  asection *s;
  for (s = abfd->sections; s != (asection *) NULL; s = s->next)
    {
      if (s->flags & SEC_LOAD)
	{
	  bfd_byte *raw_data = oasys_per_section (s)->data;
	  oasys_data_record_type processed_data;
	  bfd_size_type current_byte_index = 0;
	  unsigned int relocs_to_go = s->reloc_count;
	  arelent **p = s->orelocation;
	  if (s->reloc_count != 0)
	    {
/* Sort the reloc records so it's easy to insert the relocs into the
	   data */

	      qsort (s->orelocation,
		     s->reloc_count,
		     sizeof (arelent **),
		     comp);
	    }
	  current_byte_index = 0;
	  processed_data.relb = s->target_index | RELOCATION_TYPE_REL;

	  while (current_byte_index < s->_cooked_size)
	    {
	      /* Scan forwards by eight bytes or however much is left and see if
	       there are any relocations going on */
	      bfd_byte *mod = &processed_data.data[0];
	      bfd_byte *dst = &processed_data.data[1];

	      unsigned int i = 0;
	      *mod = 0;


	      bfd_h_put_32 (abfd, s->vma + current_byte_index,
			    processed_data.addr);

	      /* Don't start a relocation unless you're sure you can finish it
 	       within the same data record.  The worst case relocation is a
 	       4-byte relocatable value which is split across two modification
 	       bytes (1 relocation byte + 2 symbol reference bytes + 2 data +
 	       1 modification byte + 2 data = 8 bytes total).  That's where
 	       the magic number 8 comes from.
 	    */
	      while (current_byte_index < s->_raw_size && dst <=
		     &processed_data.data[sizeof (processed_data.data) - 8])
		{


		  if (relocs_to_go != 0)
		    {
		      arelent *r = *p;
		      reloc_howto_type *const how = r->howto;
		      /* There is a relocation, is it for this byte ? */
		      if (r->address == current_byte_index)
			{
			  unsigned char rel_byte;

			  p++;
			  relocs_to_go--;

			  *mod |= (1 << i);
			  if (how->pc_relative)
			    {
			      rel_byte = RELOCATION_PCREL_BIT;

			      /* Also patch the raw data so that it doesn't have
			 the -ve stuff any more */
			      if (how->size != 2)
				{
				  bfd_put_16 (abfd,
					      bfd_get_16 (abfd, raw_data) +
					      current_byte_index, raw_data);
				}

			      else
				{
				  bfd_put_32 (abfd,
					      bfd_get_32 (abfd, raw_data) +
					      current_byte_index, raw_data);
				}
			    }
			  else
			    {
			      rel_byte = 0;
			    }
			  if (how->size == 2)
			    {
			      rel_byte |= RELOCATION_32BIT_BIT;
			    }

			  /* Is this a section relative relocation, or a symbol
		       relative relocation ? */
			  abort ();

#if 0
			  if (r->section != (asection *) NULL)
			    {
			      /* The relent has a section attached, so it must be section
			     relative */
			      rel_byte |= RELOCATION_TYPE_REL;
			      rel_byte |= r->section->output_section->target_index;
			      *dst++ = rel_byte;
			    }
			  else
#endif
			    {
			      asymbol *p = *(r->sym_ptr_ptr);

			      /* If this symbol has a section attached, then it
			     has already been resolved.  Change from a symbol
			     ref to a section ref */
			      if (p->section != (asection *) NULL)
				{
				  rel_byte |= RELOCATION_TYPE_REL;
				  rel_byte |=
				    p->section->output_section->target_index;
				  *dst++ = rel_byte;
				}
			      else
				{
				  rel_byte |= RELOCATION_TYPE_UND;
				  *dst++ = rel_byte;
				  /* Next two bytes are a symbol index - we can get
			       this from the symbol value which has been zapped
			       into the symbol index in the table when the
			       symbol table was written
			       */
				  *dst++ = p->value >> 8;
				  *dst++ = p->value;
				}
			    }
#define ADVANCE { if (++i >= 8) { i = 0; mod = dst++; *mod = 0; } current_byte_index++; }
			  /* relocations never occur from an unloadable section,
		       so we can assume that raw_data is not NULL
		     */
			  *dst++ = *raw_data++;
			  ADVANCE
			    * dst++ = *raw_data++;
			  ADVANCE
			    if (how->size == 2)
			    {
			      *dst++ = *raw_data++;
			      ADVANCE
				* dst++ = *raw_data++;
			      ADVANCE
			    }
			  continue;
			}
		    }
		  /* If this is coming from an unloadable section then copy
		   zeros */
		  if (raw_data == NULL)
		    {
		      *dst++ = 0;
		    }
		  else
		    {
		      *dst++ = *raw_data++;
		    }
		  ADVANCE
		}

	      /* Don't write a useless null modification byte */
	      if (dst == mod + 1)
		{
		  --dst;
		}

	      if (! oasys_write_record (abfd,
					oasys_record_is_data_enum,
					((oasys_record_union_type *)
					 & processed_data),
					dst - (bfd_byte *) & processed_data))
		return false;
	    }
	}
    }

  return true;
}

static boolean
oasys_write_object_contents (abfd)
     bfd *abfd;
{
  if (! oasys_write_header (abfd))
    return false;
  if (! oasys_write_syms (abfd))
    return false;
  if (! oasys_write_sections (abfd))
    return false;
  if (! oasys_write_data (abfd))
    return false;
  if (! oasys_write_end (abfd))
    return false;
  return true;
}




/** exec and core file sections */

/* set section contents is complicated with OASYS since the format is
* not a byte image, but a record stream.
*/
static boolean
oasys_set_section_contents (abfd, section, location, offset, count)
     bfd *abfd;
     sec_ptr section;
     PTR location;
     file_ptr offset;
     bfd_size_type count;
{
  if (count != 0)
    {
      if (oasys_per_section (section)->data == (bfd_byte *) NULL)
	{
	  oasys_per_section (section)->data =
	    (bfd_byte *) (bfd_alloc (abfd, section->_cooked_size));
	  if (!oasys_per_section (section)->data)
	    return false;
	}
      (void) memcpy ((PTR) (oasys_per_section (section)->data + offset),
		     location,
		     (size_t) count);
    }
  return true;
}



/* Native-level interface to symbols. */

/* We read the symbols into a buffer, which is discarded when this
function exits.  We read the strings into a buffer large enough to
hold them all plus all the cached symbol entries. */

static asymbol *
oasys_make_empty_symbol (abfd)
     bfd *abfd;
{

  oasys_symbol_type *new =
  (oasys_symbol_type *) bfd_zalloc (abfd, sizeof (oasys_symbol_type));
  if (!new)
    return NULL;
  new->symbol.the_bfd = abfd;
  return &new->symbol;
}




/* User should have checked the file flags; perhaps we should return
BFD_NO_MORE_SYMBOLS if there are none? */

static bfd *
oasys_openr_next_archived_file (arch, prev)
     bfd *arch;
     bfd *prev;
{
  oasys_ar_data_type *ar = OASYS_AR_DATA (arch);
  oasys_module_info_type *p;
  /* take the next one from the arch state, or reset */
  if (prev == (bfd *) NULL)
    {
      /* Reset the index - the first two entries are bogus*/
      ar->module_index = 0;
    }

  p = ar->module + ar->module_index;
  ar->module_index++;

  if (ar->module_index <= ar->module_count)
    {
      if (p->abfd == (bfd *) NULL)
	{
	  p->abfd = _bfd_create_empty_archive_element_shell (arch);
	  p->abfd->origin = p->pos;
	  p->abfd->filename = p->name;

	  /* Fixup a pointer to this element for the member */
	  p->abfd->arelt_data = (PTR) p;
	}
      return p->abfd;
    }
  else
    {
      bfd_set_error (bfd_error_no_more_archived_files);
      return (bfd *) NULL;
    }
}

static boolean
oasys_find_nearest_line (abfd,
			 section,
			 symbols,
			 offset,
			 filename_ptr,
			 functionname_ptr,
			 line_ptr)
     bfd *abfd ATTRIBUTE_UNUSED;
     asection *section ATTRIBUTE_UNUSED;
     asymbol **symbols ATTRIBUTE_UNUSED;
     bfd_vma offset ATTRIBUTE_UNUSED;
     char **filename_ptr ATTRIBUTE_UNUSED;
     char **functionname_ptr ATTRIBUTE_UNUSED;
     unsigned int *line_ptr ATTRIBUTE_UNUSED;
{
  return false;

}

static int
oasys_generic_stat_arch_elt (abfd, buf)
     bfd *abfd;
     struct stat *buf;
{
  oasys_module_info_type *mod = (oasys_module_info_type *) abfd->arelt_data;
  if (mod == (oasys_module_info_type *) NULL)
    {
      bfd_set_error (bfd_error_invalid_operation);
      return -1;
    }
  else
    {
      buf->st_size = mod->size;
      buf->st_mode = 0666;
      return 0;
    }
}

static int
oasys_sizeof_headers (abfd, exec)
     bfd *abfd ATTRIBUTE_UNUSED;
     boolean exec ATTRIBUTE_UNUSED;
{
  return 0;
}

#define	oasys_close_and_cleanup _bfd_generic_close_and_cleanup
#define oasys_bfd_free_cached_info _bfd_generic_bfd_free_cached_info

#define oasys_slurp_armap bfd_true
#define oasys_slurp_extended_name_table bfd_true
#define oasys_construct_extended_name_table \
  ((boolean (*) PARAMS ((bfd *, char **, bfd_size_type *, const char **))) \
   bfd_true)
#define oasys_truncate_arname bfd_dont_truncate_arname
#define oasys_write_armap \
  ((boolean (*) \
    PARAMS ((bfd *, unsigned int, struct orl *, unsigned int, int))) \
   bfd_true)
#define oasys_read_ar_hdr bfd_nullvoidptr
#define oasys_get_elt_at_index _bfd_generic_get_elt_at_index
#define oasys_update_armap_timestamp bfd_true

#define oasys_bfd_is_local_label_name bfd_generic_is_local_label_name
#define oasys_get_lineno _bfd_nosymbols_get_lineno
#define oasys_bfd_make_debug_symbol _bfd_nosymbols_bfd_make_debug_symbol
#define oasys_read_minisymbols _bfd_generic_read_minisymbols
#define oasys_minisymbol_to_symbol _bfd_generic_minisymbol_to_symbol

#define oasys_bfd_reloc_type_lookup _bfd_norelocs_bfd_reloc_type_lookup

#define oasys_set_arch_mach bfd_default_set_arch_mach

#define oasys_get_section_contents_in_window \
  _bfd_generic_get_section_contents_in_window

#define oasys_bfd_get_relocated_section_contents \
  bfd_generic_get_relocated_section_contents
#define oasys_bfd_relax_section bfd_generic_relax_section
#define oasys_bfd_gc_sections bfd_generic_gc_sections
#define oasys_bfd_link_hash_table_create _bfd_generic_link_hash_table_create
#define oasys_bfd_link_add_symbols _bfd_generic_link_add_symbols
#define oasys_bfd_final_link _bfd_generic_final_link
#define oasys_bfd_link_split_section _bfd_generic_link_split_section

/*SUPPRESS 460 */
const bfd_target oasys_vec =
{
  "oasys",			/* name */
  bfd_target_oasys_flavour,
  BFD_ENDIAN_BIG,		/* target byte order */
  BFD_ENDIAN_BIG,		/* target headers byte order */
  (HAS_RELOC | EXEC_P |		/* object flags */
   HAS_LINENO | HAS_DEBUG |
   HAS_SYMS | HAS_LOCALS | WP_TEXT | D_PAGED),
  (SEC_CODE | SEC_DATA | SEC_ROM | SEC_HAS_CONTENTS
   | SEC_ALLOC | SEC_LOAD | SEC_RELOC),	/* section flags */
  0,				/* leading underscore */
  ' ',				/* ar_pad_char */
  16,				/* 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,
   oasys_object_p,		/* bfd_check_format */
   oasys_archive_p,
   _bfd_dummy_target,
  },
  {				/* bfd_set_format */
    bfd_false,
    oasys_mkobject,
    _bfd_generic_mkarchive,
    bfd_false
  },
  {				/* bfd_write_contents */
    bfd_false,
    oasys_write_object_contents,
    _bfd_write_archive_contents,
    bfd_false,
  },

  BFD_JUMP_TABLE_GENERIC (oasys),
  BFD_JUMP_TABLE_COPY (_bfd_generic),
  BFD_JUMP_TABLE_CORE (_bfd_nocore),
  BFD_JUMP_TABLE_ARCHIVE (oasys),
  BFD_JUMP_TABLE_SYMBOLS (oasys),
  BFD_JUMP_TABLE_RELOCS (oasys),
  BFD_JUMP_TABLE_WRITE (oasys),
  BFD_JUMP_TABLE_LINK (oasys),
  BFD_JUMP_TABLE_DYNAMIC (_bfd_nodynamic),

  NULL,
  
  (PTR) 0
};
