/* BFD back-end for VERSAdos-E objects.
   Copyright 1995, 1996, 1998, 1999, 2000, 2001, 2002
   Free Software Foundation, Inc.
   Written by Steve Chamberlain of Cygnus Support <sac@cygnus.com>.

   Versados is a Motorola trademark.

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

/*
   SUBSECTION
   VERSAdos-E relocateable object file format

   DESCRIPTION

   This module supports reading of VERSAdos relocateable
   object files.

   A VERSAdos file looks like contains

   o Indentification Record
   o External Symbol Definition Record
   o Object Text Recrod
   o End Record

 */

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

static bfd_boolean versados_mkobject PARAMS ((bfd *));
static bfd_boolean versados_scan PARAMS ((bfd *));
static const bfd_target *versados_object_p PARAMS ((bfd *));
static asymbol *versados_new_symbol
  PARAMS ((bfd *, int, const char *, bfd_vma, asection *));
static char *new_symbol_string PARAMS ((bfd *, const char *));
static const bfd_target *versados_object_p PARAMS ((bfd *));
static bfd_boolean versados_pass_2 PARAMS ((bfd *));
static bfd_boolean versados_get_section_contents
  PARAMS ((bfd *, asection *, void *, file_ptr, bfd_size_type));
static bfd_boolean versados_set_section_contents
  PARAMS ((bfd *, sec_ptr, void *, file_ptr, bfd_size_type));
static int versados_sizeof_headers PARAMS ((bfd *, bfd_boolean));
static long int versados_get_symtab_upper_bound PARAMS ((bfd *));
static long int versados_get_symtab PARAMS ((bfd *, asymbol **));
static void versados_get_symbol_info
  PARAMS ((bfd *, asymbol *, symbol_info *));
static void versados_print_symbol
  PARAMS ((bfd *, PTR, asymbol *, bfd_print_symbol_type));
static long versados_get_reloc_upper_bound
  PARAMS ((bfd *, sec_ptr));
static long versados_canonicalize_reloc
  PARAMS ((bfd *, sec_ptr, arelent **, asymbol **));

#define VHEADER '1'
#define VESTDEF '2'
#define VOTR '3'
#define VEND '4'

#define ES_BASE 17		/* first symbol has esdid 17 */

/* Per file target dependent information */

/* one for each section */
struct esdid
  {
    asection *section;		/* ptr to bfd version */
    unsigned char *contents;	/* used to build image */
    int pc;
    int relocs;			/* reloc count, valid end of pass 1 */
    int donerel;		/* have relocs been translated */
  };

typedef struct versados_data_struct
  {
    int es_done;		/* count of symbol index, starts at ES_BASE */
    asymbol *symbols;		/* pointer to local symbols */
    char *strings;		/* strings of all the above */
    int stringlen;		/* len of string table (valid end of pass1) */
    int nsecsyms;		/* number of sections */

    int ndefs;			/* number of exported symbols (they dont get esdids) */
    int nrefs;			/* number of imported symbols  (valid end of pass1) */

    int ref_idx;		/* current processed value of the above */
    int def_idx;

    int pass_2_done;

    struct esdid e[16];		/* per section info */
    int alert;			/* to see if we're trampling */
    asymbol *rest[256 - 16];	/* per symbol info */

  }
tdata_type;

#define VDATA(abfd)       (abfd->tdata.versados_data)
#define EDATA(abfd, n)    (abfd->tdata.versados_data->e[n])
#define RDATA(abfd, n)    (abfd->tdata.versados_data->rest[n])

struct ext_otr
  {
    unsigned char size;
    char type;
    unsigned char map[4];
    unsigned char esdid;
    unsigned char data[200];
  };

struct ext_vheader
  {
    unsigned char size;
    char type;			/* record type */
    char name[10];		/* module name */
    char rev;			/* module rev number */
    char lang;
    char vol[4];
    char user[2];
    char cat[8];
    char fname[8];
    char ext[2];
    char time[3];
    char date[3];
    char rest[211];
  };

struct ext_esd
  {
    unsigned char size;
    char type;
    unsigned char esd_entries[1];
  };
#define ESD_ABS 	0
#define ESD_COMMON 	1
#define ESD_STD_REL_SEC 2
#define ESD_SHRT_REL_SEC 3
#define ESD_XDEF_IN_SEC 4
#define ESD_XREF_SYM    7
#define ESD_XREF_SEC	6
#define ESD_XDEF_IN_ABS 5
union ext_any
  {
    unsigned char size;
    struct ext_vheader header;
    struct ext_esd esd;
    struct ext_otr otr;
  };

static int get_record PARAMS ((bfd *, union ext_any *));
static int get_4 PARAMS ((unsigned char **));
static void get_10 PARAMS ((unsigned char **, char *));
static void process_esd PARAMS ((bfd *, struct ext_esd *, int));
static int get_offset PARAMS ((int, unsigned char *));
static void process_otr PARAMS ((bfd *, struct ext_otr *, int));

/* Initialize by filling in the hex conversion array.  */

/* Set up the tdata information.  */

static bfd_boolean
versados_mkobject (abfd)
     bfd *abfd;
{
  if (abfd->tdata.versados_data == NULL)
    {
      bfd_size_type amt = sizeof (tdata_type);
      tdata_type *tdata = (tdata_type *) bfd_alloc (abfd, amt);
      if (tdata == NULL)
	return FALSE;
      abfd->tdata.versados_data = tdata;
      tdata->symbols = NULL;
      VDATA (abfd)->alert = 0x12345678;
    }

  bfd_default_set_arch_mach (abfd, bfd_arch_m68k, 0);
  return TRUE;
}

/* Report a problem in an S record file.  FIXME: This probably should
   not call fprintf, but we really do need some mechanism for printing
   error messages.  */

static asymbol *
versados_new_symbol (abfd, snum, name, val, sec)
     bfd *abfd;
     int snum;
     const char *name;
     bfd_vma val;
     asection *sec;
{
  asymbol *n = VDATA (abfd)->symbols + snum;
  n->name = name;
  n->value = val;
  n->section = sec;
  n->the_bfd = abfd;
  n->flags = 0;
  return n;
}

static int
get_record (abfd, ptr)
     bfd *abfd;
     union ext_any *ptr;
{
  if (bfd_bread (&ptr->size, (bfd_size_type) 1, abfd) != 1
      || (bfd_bread ((char *) ptr + 1, (bfd_size_type) ptr->size, abfd)
	  != ptr->size))
    return 0;
  return 1;
}

static int
get_4 (pp)
     unsigned char **pp;
{
  unsigned char *p = *pp;
  *pp += 4;
  return (p[0] << 24) | (p[1] << 16) | (p[2] << 8) | (p[3] << 0);
}

static void
get_10 (pp, name)
     unsigned char **pp;
     char *name;
{
  char *p = (char *) *pp;
  int len = 10;
  *pp += len;
  while (*p != ' '
	 && len)
    {
      *name++ = *p++;
      len--;
    }
  *name = 0;
}

static char *
new_symbol_string (abfd, name)
     bfd *abfd;
     const char *name;
{
  char *n = VDATA (abfd)->strings;
  strcpy (VDATA (abfd)->strings, name);
  VDATA (abfd)->strings += strlen (VDATA (abfd)->strings) + 1;
  return n;
}

static void
process_esd (abfd, esd, pass)
     bfd *abfd;
     struct ext_esd *esd;
     int pass;
{
  /* Read through the ext def for the est entries */
  int togo = esd->size - 2;
  bfd_vma size;
  bfd_vma start;
  asection *sec;
  char name[11];
  unsigned char *ptr = esd->esd_entries;
  unsigned char *end = ptr + togo;
  while (ptr < end)
    {
      int scn = *ptr & 0xf;
      int typ = (*ptr >> 4) & 0xf;

      /* Declare this section */
      sprintf (name, "%d", scn);
      sec = bfd_make_section_old_way (abfd, strdup (name));
      sec->target_index = scn;
      EDATA (abfd, scn).section = sec;
      ptr++;
      switch (typ)
	{
	default:
	  abort ();
	case ESD_XREF_SEC:
	case ESD_XREF_SYM:
	  {
	    int snum = VDATA (abfd)->ref_idx++;
	    get_10 (&ptr, name);
	    if (pass == 1)
	      {
		VDATA (abfd)->stringlen += strlen (name) + 1;
	      }
	    else
	      {
		int esidx;
		asymbol *s;
		char *n = new_symbol_string (abfd, name);
		s = versados_new_symbol (abfd, snum, n, (bfd_vma) 0,
					 bfd_und_section_ptr);
		esidx = VDATA (abfd)->es_done++;
		RDATA (abfd, esidx - ES_BASE) = s;
	      }
	  }
	  break;

	case ESD_ABS:
	  size = get_4 (&ptr);
	  start = get_4 (&ptr);
	  break;
	case ESD_STD_REL_SEC:
	case ESD_SHRT_REL_SEC:
	  {
	    sec->_raw_size = get_4 (&ptr);
	    sec->flags |= SEC_ALLOC;
	  }
	  break;
	case ESD_XDEF_IN_ABS:
	  sec = (asection *) & bfd_abs_section;
	case ESD_XDEF_IN_SEC:
	  {
	    int snum = VDATA (abfd)->def_idx++;
	    bfd_vma val;
	    get_10 (&ptr, name);
	    val = get_4 (&ptr);
	    if (pass == 1)
	      {
		/* Just remember the symbol */
		VDATA (abfd)->stringlen += strlen (name) + 1;
	      }
	    else
	      {
		asymbol *s;
		char *n = new_symbol_string (abfd, name);
		s = versados_new_symbol (abfd, snum + VDATA (abfd)->nrefs, n,
					 val, sec);
		s->flags |= BSF_GLOBAL;
	      }
	  }
	  break;
	}
    }
}

#define R_RELWORD 1
#define R_RELLONG 2
#define R_RELWORD_NEG 3
#define R_RELLONG_NEG 4

reloc_howto_type versados_howto_table[] =
{
  HOWTO (R_RELWORD, 0, 1, 16, FALSE,
	 0, complain_overflow_dont, 0,
	 "+v16", TRUE, 0x0000ffff, 0x0000ffff, FALSE),
  HOWTO (R_RELLONG, 0, 2, 32, FALSE,
	 0, complain_overflow_dont, 0,
	 "+v32", TRUE, 0xffffffff, 0xffffffff, FALSE),

  HOWTO (R_RELWORD_NEG, 0, -1, 16, FALSE,
	 0, complain_overflow_dont, 0,
	 "-v16", TRUE, 0x0000ffff, 0x0000ffff, FALSE),
  HOWTO (R_RELLONG_NEG, 0, -2, 32, FALSE,
	 0, complain_overflow_dont, 0,
	 "-v32", TRUE, 0xffffffff, 0xffffffff, FALSE),
};

static int
get_offset (len, ptr)
     int len;
     unsigned char *ptr;
{
  int val = 0;
  if (len)
    {
      int i;
      val = *ptr++;
      if (val & 0x80)
	val |= ~0xff;
      for (i = 1; i < len; i++)
	val = (val << 8) | *ptr++;
    }

  return val;
}

static void
process_otr (abfd, otr, pass)
     bfd *abfd;
     struct ext_otr *otr;
     int pass;
{
  unsigned long shift;
  unsigned char *srcp = otr->data;
  unsigned char *endp = (unsigned char *) otr + otr->size;
  unsigned int bits = (otr->map[0] << 24)
  | (otr->map[1] << 16)
  | (otr->map[2] << 8)
  | (otr->map[3] << 0);

  struct esdid *esdid = &EDATA (abfd, otr->esdid - 1);
  unsigned char *contents = esdid->contents;
  int need_contents = 0;
  unsigned int dst_idx = esdid->pc;

  for (shift = ((unsigned long) 1 << 31); shift && srcp < endp; shift >>= 1)
    {
      if (bits & shift)
	{
	  int flag = *srcp++;
	  int esdids = (flag >> 5) & 0x7;
	  int sizeinwords = ((flag >> 3) & 1) ? 2 : 1;
	  int offsetlen = flag & 0x7;
	  int j;

	  if (esdids == 0)
	    {
	      /* A zero esdid means the new pc is the offset given */
	      dst_idx += get_offset (offsetlen, srcp);
	      srcp += offsetlen;
	    }
	  else
	    {
	      int val = get_offset (offsetlen, srcp + esdids);
	      if (pass == 1)
		need_contents = 1;
	      else
		for (j = 0; j < sizeinwords * 2; j++)
		  {
		    contents[dst_idx + (sizeinwords * 2) - j - 1] = val;
		    val >>= 8;
		  }

	      for (j = 0; j < esdids; j++)
		{
		  int esdid = *srcp++;

		  if (esdid)
		    {
		      int rn = EDATA (abfd, otr->esdid - 1).relocs++;
		      if (pass == 1)
			{
			  /* this is the first pass over the data,
			     just remember that we need a reloc */
			}
		      else
			{
			  arelent *n =
			  EDATA (abfd, otr->esdid - 1).section->relocation + rn;
			  n->address = dst_idx;

			  n->sym_ptr_ptr = (asymbol **) esdid;
			  n->addend = 0;
			  n->howto = versados_howto_table + ((j & 1) * 2) + (sizeinwords - 1);
			}
		    }
		}
	      srcp += offsetlen;
	      dst_idx += sizeinwords * 2;
	    }
	}
      else
	{
	  need_contents = 1;
	  if (dst_idx < esdid->section->_raw_size)
	    if (pass == 2)
	      {
		/* absolute code, comes in 16 bit lumps */
		contents[dst_idx] = srcp[0];
		contents[dst_idx + 1] = srcp[1];
	      }
	  dst_idx += 2;
	  srcp += 2;
	}
    }
  EDATA (abfd, otr->esdid - 1).pc = dst_idx;

  if (!contents && need_contents)
    {
      bfd_size_type size = esdid->section->_raw_size;
      esdid->contents = (unsigned char *) bfd_alloc (abfd, size);
    }
}

static bfd_boolean
versados_scan (abfd)
     bfd *abfd;
{
  int loop = 1;
  int i;
  int j;
  int nsecs = 0;
  bfd_size_type amt;

  VDATA (abfd)->stringlen = 0;
  VDATA (abfd)->nrefs = 0;
  VDATA (abfd)->ndefs = 0;
  VDATA (abfd)->ref_idx = 0;
  VDATA (abfd)->def_idx = 0;
  VDATA (abfd)->pass_2_done = 0;

  while (loop)
    {
      union ext_any any;
      if (!get_record (abfd, &any))
	return TRUE;
      switch (any.header.type)
	{
	case VHEADER:
	  break;
	case VEND:
	  loop = 0;
	  break;
	case VESTDEF:
	  process_esd (abfd, &any.esd, 1);
	  break;
	case VOTR:
	  process_otr (abfd, &any.otr, 1);
	  break;
	}
    }

  /* Now allocate space for the relocs and sections */

  VDATA (abfd)->nrefs = VDATA (abfd)->ref_idx;
  VDATA (abfd)->ndefs = VDATA (abfd)->def_idx;
  VDATA (abfd)->ref_idx = 0;
  VDATA (abfd)->def_idx = 0;

  abfd->symcount = VDATA (abfd)->nrefs + VDATA (abfd)->ndefs;

  for (i = 0; i < 16; i++)
    {
      struct esdid *esdid = &EDATA (abfd, i);
      if (esdid->section)
	{
	  amt = (bfd_size_type) esdid->relocs * sizeof (arelent);
	  esdid->section->relocation = (arelent *) bfd_alloc (abfd, amt);

	  esdid->pc = 0;

	  if (esdid->contents)
	    esdid->section->flags |= SEC_HAS_CONTENTS | SEC_LOAD;

	  esdid->section->reloc_count = esdid->relocs;
	  if (esdid->relocs)
	    esdid->section->flags |= SEC_RELOC;

	  esdid->relocs = 0;

	  /* Add an entry into the symbol table for it */
	  nsecs++;
	  VDATA (abfd)->stringlen += strlen (esdid->section->name) + 1;
	}
    }

  abfd->symcount += nsecs;

  amt = abfd->symcount;
  amt *= sizeof (asymbol);
  VDATA (abfd)->symbols = (asymbol *) bfd_alloc (abfd, amt);

  amt = VDATA (abfd)->stringlen;
  VDATA (abfd)->strings = bfd_alloc (abfd, amt);

  if ((VDATA (abfd)->symbols == NULL && abfd->symcount > 0)
      || (VDATA (abfd)->strings == NULL && VDATA (abfd)->stringlen > 0))
    return FALSE;

  /* Actually fill in the section symbols,
     we stick them at the end of the table */

  for (j = VDATA (abfd)->nrefs + VDATA (abfd)->ndefs, i = 0; i < 16; i++)
    {
      struct esdid *esdid = &EDATA (abfd, i);
      asection *sec = esdid->section;
      if (sec)
	{
	  asymbol *s = VDATA (abfd)->symbols + j;
	  s->name = new_symbol_string (abfd, sec->name);
	  s->section = sec;
	  s->flags = BSF_LOCAL;
	  s->value = 0;
	  s->the_bfd = abfd;
	  j++;
	}
    }
  if (abfd->symcount)
    abfd->flags |= HAS_SYMS;

  /* Set this to nsecs - since we've already planted the section
     symbols */
  VDATA (abfd)->nsecsyms = nsecs;

  VDATA (abfd)->ref_idx = 0;

  return 1;
}

/* Check whether an existing file is a versados  file.  */

static const bfd_target *
versados_object_p (abfd)
     bfd *abfd;
{
  struct ext_vheader ext;
  unsigned char len;
  tdata_type *tdata_save;

  if (bfd_seek (abfd, (file_ptr) 0, SEEK_SET) != 0)
    return NULL;

  if (bfd_bread (&len, (bfd_size_type) 1, abfd) != 1)
    {
      if (bfd_get_error () != bfd_error_system_call)
	bfd_set_error (bfd_error_wrong_format);
      return NULL;
    }

  if (bfd_bread (&ext.type, (bfd_size_type) len, abfd) != len)
    {
      if (bfd_get_error () != bfd_error_system_call)
	bfd_set_error (bfd_error_wrong_format);
      return NULL;
    }

  /* We guess that the language field will never be larger than 10.
     In sample files, it is always either 0 or 1.  Checking for this
     prevents confusion with Intel Hex files.  */
  if (ext.type != VHEADER
      || ext.lang > 10)
    {
      bfd_set_error (bfd_error_wrong_format);
      return NULL;
    }

  /* OK, looks like a record, build the tdata and read in.  */

  tdata_save = abfd->tdata.versados_data;
  if (!versados_mkobject (abfd) || !versados_scan (abfd))
    {
      abfd->tdata.versados_data = tdata_save;
      return NULL;
    }

  return abfd->xvec;
}

static bfd_boolean
versados_pass_2 (abfd)
     bfd *abfd;
{
  union ext_any any;

  if (VDATA (abfd)->pass_2_done)
    return 1;

  if (bfd_seek (abfd, (file_ptr) 0, SEEK_SET) != 0)
    return 0;

  VDATA (abfd)->es_done = ES_BASE;

  /* read records till we get to where we want to be */

  while (1)
    {
      get_record (abfd, &any);
      switch (any.header.type)
	{
	case VEND:
	  VDATA (abfd)->pass_2_done = 1;
	  return 1;
	case VESTDEF:
	  process_esd (abfd, &any.esd, 2);
	  break;
	case VOTR:
	  process_otr (abfd, &any.otr, 2);
	  break;
	}
    }
}

static bfd_boolean
versados_get_section_contents (abfd, section, location, offset, count)
     bfd *abfd;
     asection *section;
     PTR location;
     file_ptr offset;
     bfd_size_type count;
{
  if (!versados_pass_2 (abfd))
    return FALSE;

  memcpy (location,
	  EDATA (abfd, section->target_index).contents + offset,
	  (size_t) count);

  return TRUE;
}

#define versados_get_section_contents_in_window \
  _bfd_generic_get_section_contents_in_window

static bfd_boolean
versados_set_section_contents (abfd, section, location, offset, bytes_to_do)
     bfd *abfd ATTRIBUTE_UNUSED;
     sec_ptr section ATTRIBUTE_UNUSED;
     PTR location ATTRIBUTE_UNUSED;
     file_ptr offset ATTRIBUTE_UNUSED;
     bfd_size_type bytes_to_do ATTRIBUTE_UNUSED;
{
  return FALSE;
}

static int
versados_sizeof_headers (abfd, exec)
     bfd *abfd ATTRIBUTE_UNUSED;
     bfd_boolean exec ATTRIBUTE_UNUSED;
{
  return 0;
}

/* Return the amount of memory needed to read the symbol table.  */

static long
versados_get_symtab_upper_bound (abfd)
     bfd *abfd;
{
  return (bfd_get_symcount (abfd) + 1) * sizeof (asymbol *);
}

/* Return the symbol table.  */

static long
versados_get_symtab (abfd, alocation)
     bfd *abfd;
     asymbol **alocation;
{
  unsigned int symcount = bfd_get_symcount (abfd);
  unsigned int i;
  asymbol *s;

  versados_pass_2 (abfd);

  for (i = 0, s = VDATA (abfd)->symbols;
       i < symcount;
       s++, i++)
    {
      *alocation++ = s;
    }

  *alocation = NULL;

  return symcount;
}

static void
versados_get_symbol_info (ignore_abfd, symbol, ret)
     bfd *ignore_abfd ATTRIBUTE_UNUSED;
     asymbol *symbol;
     symbol_info *ret;
{
  bfd_symbol_info (symbol, ret);
}

static void
versados_print_symbol (abfd, afile, symbol, how)
     bfd *abfd;
     PTR afile;
     asymbol *symbol;
     bfd_print_symbol_type how;
{
  FILE *file = (FILE *) afile;
  switch (how)
    {
    case bfd_print_symbol_name:
      fprintf (file, "%s", symbol->name);
      break;
    default:
      bfd_print_symbol_vandf (abfd, (PTR) file, symbol);
      fprintf (file, " %-5s %s",
	       symbol->section->name,
	       symbol->name);

    }
}

static long
versados_get_reloc_upper_bound (abfd, asect)
     bfd *abfd ATTRIBUTE_UNUSED;
     sec_ptr asect;
{
  return (asect->reloc_count + 1) * sizeof (arelent *);
}

static long
versados_canonicalize_reloc (abfd, section, relptr, symbols)
     bfd *abfd;
     sec_ptr section;
     arelent **relptr;
     asymbol **symbols;
{
  unsigned int count;
  arelent *src;

  versados_pass_2 (abfd);
  src = section->relocation;
  if (!EDATA (abfd, section->target_index).donerel)
    {
      EDATA (abfd, section->target_index).donerel = 1;
      /* translate from indexes to symptr ptrs */
      for (count = 0; count < section->reloc_count; count++)
	{
	  int esdid = (int) src[count].sym_ptr_ptr;

	  if (esdid == 0)
	    {
	      src[count].sym_ptr_ptr = bfd_abs_section.symbol_ptr_ptr;
	    }
	  else if (esdid < ES_BASE)	/* Section relative thing */
	    {
	      struct esdid *e = &EDATA (abfd, esdid - 1);
	      if (!section)
		{
		 /** relocation relative to section which was
		   never declared ! */
		}
	      src[count].sym_ptr_ptr = e->section->symbol_ptr_ptr;
	    }
	  else
	    {
	      src[count].sym_ptr_ptr = symbols + esdid - ES_BASE;
	    }

	}
    }

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

#define	versados_close_and_cleanup _bfd_generic_close_and_cleanup
#define versados_bfd_free_cached_info _bfd_generic_bfd_free_cached_info
#define versados_new_section_hook _bfd_generic_new_section_hook

#define versados_bfd_is_local_label_name bfd_generic_is_local_label_name
#define versados_get_lineno _bfd_nosymbols_get_lineno
#define versados_find_nearest_line _bfd_nosymbols_find_nearest_line
#define versados_make_empty_symbol _bfd_generic_make_empty_symbol
#define versados_bfd_make_debug_symbol _bfd_nosymbols_bfd_make_debug_symbol
#define versados_read_minisymbols _bfd_generic_read_minisymbols
#define versados_minisymbol_to_symbol _bfd_generic_minisymbol_to_symbol

#define versados_bfd_reloc_type_lookup _bfd_norelocs_bfd_reloc_type_lookup

#define versados_set_arch_mach bfd_default_set_arch_mach

#define versados_bfd_get_relocated_section_contents \
  bfd_generic_get_relocated_section_contents
#define versados_bfd_relax_section bfd_generic_relax_section
#define versados_bfd_gc_sections bfd_generic_gc_sections
#define versados_bfd_merge_sections bfd_generic_merge_sections
#define versados_bfd_discard_group bfd_generic_discard_group
#define versados_bfd_link_hash_table_create _bfd_generic_link_hash_table_create
#define versados_bfd_link_hash_table_free _bfd_generic_link_hash_table_free
#define versados_bfd_link_add_symbols _bfd_generic_link_add_symbols
#define versados_bfd_link_just_syms _bfd_generic_link_just_syms
#define versados_bfd_final_link _bfd_generic_final_link
#define versados_bfd_link_split_section _bfd_generic_link_split_section

const bfd_target versados_vec =
{
  "versados",			/* name */
  bfd_target_versados_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,
    versados_object_p,		/* bfd_check_format */
    _bfd_dummy_target,
    _bfd_dummy_target,
  },
  {
    bfd_false,
    versados_mkobject,
    _bfd_generic_mkarchive,
    bfd_false,
  },
  {				/* bfd_write_contents */
    bfd_false,
    bfd_false,
    _bfd_write_archive_contents,
    bfd_false,
  },

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

  NULL,

  (PTR) 0
};
