{ bfd_set_error (bfd_error_no_memory); return false; }
return false;
static const bfd_target *versados_object_p PARAMS ((bfd *));#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 5union ext_any  {    unsigned char size;    struct ext_vheader header;    struct ext_esd esd;    struct ext_otr otr;  };/* Initialize by filling in the hex conversion array. *//* Set up the tdata information.  */static booleanversados_mkobject (abfd)     bfd *abfd;{  if (abfd->tdata.versados_data == NULL)    {      tdata_type *tdata = (tdata_type *) bfd_alloc (abfd, sizeof (tdata_type));      if (tdata == NULL)	{	  bfd_set_error (bfd_error_no_memory);	  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 intget_record (abfd, ptr)     bfd *abfd;     union ext_any *ptr;{  bfd_read (&ptr->size, 1, 1, abfd);  if (bfd_read ((char *) ptr + 1, 1, ptr->size, abfd) != ptr->size)    return 0;  return 1;}intget_4 (pp)     unsigned char **pp;{  unsigned char *p = *pp;  *pp += 4;  return (p[0] << 24) | (p[1] << 16) | (p[2] << 8) | (p[3] << 0);}voidget_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;     char *name;{  char *n = VDATA (abfd)->strings;  strcpy (VDATA (abfd)->strings, name);  VDATA (abfd)->strings += strlen (VDATA (abfd)->strings) + 1;  return n;}static voidprocess_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, 0,					 &bfd_und_section, scn);		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++;	    long 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, scn);		s->flags |= BSF_GLOBAL;	      }	  }	  break;	}    }}#define R_RELWORD 1#define R_RELLONG 2#define R_RELWORD_NEG 3#define R_RELLONG_NEG 4reloc_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 intget_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 voidprocess_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 = (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)    esdid->contents = (unsigned char *) bfd_alloc (abfd, esdid->section->_raw_size);}static booleanversados_scan (abfd)     bfd *abfd;{  int loop = 1;  int i;  int j;  int nsecs = 0;  VDATA (abfd)->nrefs = 0;  VDATA (abfd)->ndefs = 0;  VDATA (abfd)->ref_idx = 0;  VDATA (abfd)->def_idx = 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)	{	  esdid->section->relocation	    = (arelent *) bfd_alloc (abfd, sizeof (arelent) * esdid->relocs);	  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;  VDATA (abfd)->symbols = (asymbol *) bfd_alloc (abfd,				       sizeof (asymbol) * (abfd->symcount));  VDATA (abfd)->strings = bfd_alloc (abfd, VDATA (abfd)->stringlen);  /* 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;  if (bfd_seek (abfd, (file_ptr) 0, SEEK_SET))    return NULL;  bfd_read (&len, 1, 1, abfd);  if (bfd_read (&ext.type, 1, len, abfd) != len      || ext.type != '1')    {      bfd_set_error (bfd_error_wrong_format);      return NULL;    }  /* ok, looks like a record, build the tdata and read      in.. */  if (!versados_mkobject (abfd)      || !versados_scan (abfd))    return NULL;  return abfd->xvec;}